我正在使用 gradle 构建一个 springboot 应用程序进行依赖管理,并使用 docker compose 构建我的 CI 管道。我的工作箱正在运行 MacOS Ventura
当我尝试使用
gradle build
命令在本地构建应用程序时,一切都会按预期进行;但是,当我在 docker-compose 文件中尝试相同的命令时,遇到了看似 SSL 错误。这似乎是因为我的公司正在使用 Netskope 通过使用其自己的自签名证书重定向我们的请求来监控我们的网络流量,而当我尝试构建我的应用程序时,docker 守护进程并不知道这些证书。
docker-compose.yml
version: "3"
services:
# Gradle build image
my-application-gradle-build:
image: gradle:7.6.4-jdk11
volumes:
- .:/home/gradle/project
- ~/.gradle/gradle.properties:/home/gradle/.gradle/gradle.properties
- ~/.m2:/home/gradle/.m2
working_dir: /home/gradle/project
command: gradle --no-daemon build
上传到我们的 CI 平台 (Bamboo) 时,我的构建作业以相同的方式调用此命令,并且完成时没有错误。
我尝试过的
尝试了2种方式:
docker-compose.yml
version: "3"
services:
# Gradle build image
my-application-gradle-build:
image: gradle:7.6.4-jdk11
volumes:
- .:/home/gradle/project
- ~/.gradle/gradle.properties:/home/gradle/.gradle/gradle.properties
- ~/.m2:/home/gradle/.m2
- ~/.certs:/Library/Application\ Support/Netskope/STAgent/data/nscacert.pem
DOCKERFILE
FROM eclipse-temurin:11-jdk-jammy
COPY /Library/Application\\ Support/Netskope/STAgent/data/nscacert.pem /tmp
RUN keytool -import -trustcacerts -file /tmp/nscacert.pem -alias MyCertificate -keystore $JAVA_HOME/jre/lib/security/cacerts -storepass changeit -noprompt
EXPOSE 12533
COPY \*.jar my-application.jar
CMD java ${JAVA_OPTS} -jar my-application.jar
使用
DOCKER_TLS_VERIFY=0
命令行 arg 禁用 TLS 验证
将以下插件存储库定义添加到settings.gradle.kts
pluginManagement {
repositories {
gradlePluginPortal()
google()
mavenCentral()
}
}
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
}
}
当尝试在没有上述插件存储库定义的情况下运行我的 docker-compose.yml 文件时,构建在它尝试拉取的第一个依赖项(springboot gradle 插件)上失败,并在 this gradle 社区帖子
中发现相同的错误但是,当我将存储库定义添加到 settings.gradle.kts 时,我可以看到一堆失败的 SSL 握手异常,并显示以下消息:
javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
我怀疑我需要以某种方式配置 gradle:7.6.4-jdk11 下载的 jre 以信任 Netskope 的自签名证书,但到目前为止我尝试过的所有操作都导致了相同的 SSL 错误
#2:DOCKER_TLS_VERIFY 仅适用于 docker client 和 docker daemon 之间的通信,甚至在使用默认 Unix 域套接字时也不适用;它对任何容器或图像都没有影响。
#1B:在 Java 9 中,文件是
$JAVA_HOME/lib/security/cacerts
(不再是 jre
),你的 RUN keytool -importcert
应该给出 FileNotFoundException 和状态 1 ——但你不需要拼写出来,因为在 9 中您可以使用 选项 -cacerts
代替 -keystore $correct_file
。然而,这只适用于您的应用程序运行容器,而不适用于您的(库存)gradle,并且我认为您需要 gradle 在运行应用程序之前构建应用程序。
temurin 和 gradle 图像都使用 __cacert_entrypoint hack,因此您可以对两者使用相同的解决方案: