使用 Palantir Gradle 插件构建 Docker 容器时找不到 .jar 文件
Posted
技术标签:
【中文标题】使用 Palantir Gradle 插件构建 Docker 容器时找不到 .jar 文件【英文标题】:.jar file not found when building a Docker container with Palantir Gradle plug-in 【发布时间】:2018-10-01 04:32:58 【问题描述】:如果我尝试在 Windows 10 下使用 Spring Boot 应用程序构建 Docker 容器,我会收到以下错误:
> Task :docker FAILED
COPY failed: stat /var/lib/docker/tmp/docker-builder711841135/myproject.jar: no such file or directory
我正在使用版本 18.03.0-ce-win59 (16762) 的 Docker 社区版和带有 Java 8 的 Gradle 4.7。
build.gradle(缩短):
plugins
id 'java'
id 'org.springframework.boot' version '2.0.1.RELEASE'
id "com.palantir.docker" version "0.19.2"
version = '2.0.0'
sourceCompatibility = 1.8
group = "com.example"
repositories
mavenCentral()
bootJar
archiveName 'myproject.jar'
dependencies
...
docker
dependsOn(build)
name "$project.group/$jar.baseName"
files bootJar
Dockerfile(顶层项目目录中 build.gradle 的兄弟):
FROM openjdk:8-jre
COPY build/libs/myproject.jar myproject.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/myproject.jar"]
如果我只使用 Docker(没有 Gradle)构建 Docker 容器,它就可以工作。
如何让 Gradle(或 Docker?)找到 myproject.jar 文件?
【问题讨论】:
你试过COPY build/libs/myproject.jar /
吗?
@ThanhNguyenVan 是的,我也试过了,但错误是一样的。源目录好像有问题。
服务器上是否有 build/libs/myproject.jar 文件?
该文件存在于 Gradle 项目的结构中。 “在服务器上”是什么意思?我在我的开发机器上本地运行 Docker 作为 Windows 服务。我有什么事情可以将文件提交到 docker 吗?
文件在这里:C:\Users\me\projects\myproject\trunk\Java\myproject\build\libs\myproject.jar
,我从C:\Users\me\projects\myproject\trunk\Java\myproject
开始Gradle。
【参考方案1】:
我遇到了类似的问题。这是我花了很多时间后的working solution:-
build.gradle
String imageName = "$project.group/$project.name"
docker
//dependsOn build
dockerfile file('Dockerfile')
name imageName
files bootJar.archiveFile.get()
buildArgs(['JAR_FILE': "$bootJar.archiveFileName.get()"])
dockerRun
name "$project.name-container"
image imageName
ports '8081:8081'
env 'SPRING_PROFILES_ACTIVE': 'dev'
daemonize true
clean false
Jenkins 文件
FROM adoptopenjdk/openjdk11:alpine-jre
ARG APP_NAME="product-service"
ARG APP_VERSION="0.0.1"
ARG JAR_FILE="/build/libs/$APP_NAME-$APP_VERSION.jar"
COPY $JAR_FILE app.jar
ENTRYPOINT ["java","-jar", "app.jar"]
这适用于 Gradle 任务 :docker
和 :dockerRun
。它也适用于 docker 命令行。
【讨论】:
【参考方案2】:问题在于 Docker 文件中的COPY
命令:
COPY build/libs/myproject.jar myproject.jar
源目录build/libs/
不是用于构建 Docker 容器的文件所在的位置。相反,目录 build/docker/
用作 Docker 构建上下文。当COPY
被执行时,这个目录是有效的工作目录。
正确的COPY
命令就这么简单:
COPY myproject.jar /
Docker 任务:
docker
dependsOn bootJar
name "$project.group/$jar.baseName:$version"
files bootJar.archivePath
如果你也想复制资源,你需要在files
参数中添加processResources
:
files bootJar.archivePath, processResources
【讨论】:
不错,比我的回答更准确。 +1【参考方案3】:它适用于docker
任务的以下配置:
docker
dependsOn build
name "$project.group/$jar.baseName"
files bootJar.archivePath
buildArgs(['JAR_FILE': "$bootJar.archiveName"])
使用这个略有不同的 docker 文件:
FROM openjdk:8-jre
ARG JAR_FILE
COPY $JAR_FILE app.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
【讨论】:
【参考方案4】:这似乎与 palantir/gradle-docker issue 76 一致,它指定:
我根据示例配置了一个新项目,我观察到整个项目(减去
build/
)被复制到build/docker
。我会导致不必要的大型 docker 构建上下文。
COPY
应该是build/docker/libs/myproject.jar
,或者build/
本身根本不包括在内。
该问题提到了覆盖另一个 docker 步骤的可能解决方法 - dockerPrepare
- 明确准备“build/docker
”文件夹。
除了 Dockerfile 之外,我只需要一个 fatJar:
task dockerCopy(type: MoveTo, dependsOn: dockerPrepare)
from('build/packed')
include "$jarFullName"
into 'build/docker'
【讨论】:
谢谢。但是在我的情况下找不到MoveTo
:“无法为根项目获取未知属性'MoveTo'”。但看起来这个问题可以通过 docker
任务的不同配置来解决。我将在这里发布我的解决方案。【参考方案5】:
你的 gradle "destinationDir" 是什么?
生成的 jar 将位于destinationDir/archiveName 中。也许是 target/myproject.jar
所以你应该把:
COPY target/myproject.jar myproject.jar
如果它不起作用,请添加您的 gradle :
destinationDir target
【讨论】:
谢谢。我尝试使用COPY build/libs/myproject.jar myproject.jar
并在bootJar
任务(destinationDir file('target')
)和COPY target/myproject.jar myproject.jar
中明确设置destinationDir
,但我得到的只是错误消息中的路径略有不同:COPY failed: stat /var/lib/docker/tmp/docker-builder548809975/target/myproject.jar
。跨度>
以上是关于使用 Palantir Gradle 插件构建 Docker 容器时找不到 .jar 文件的主要内容,如果未能解决你的问题,请参考以下文章
Android Gradle 插件Gradle 扩展属性 ② ( 定义在根目录 build.gradle 中的扩展属性 | 使用 rootProject.扩展属性名访问 | 扩展属性示例 )
Android Gradle 插件Gradle 扩展属性 ② ( 定义在根目录 build.gradle 中的扩展属性 | 使用 rootProject.扩展属性名访问 | 扩展属性示例 )
Android Gradle 插件Gradle 构建工具简介 ③ ( Gradle 构建脚本编程语言 | Groovy 语言简介 | Groovy 语言特性 )
Android Gradle 插件组件化中的 Gradle 构建脚本实现 ④ ( 使用路由实现组件间通信 | 引入 ARoute 框架 | Gradle 构建脚本优化问题 )