Docker:在Dockerfile中,临时复制文件,但不能复制最终的图像

我有一个我想打包的Java服务,最终的Docker镜像只需要JAR文件和一个configuration文件。 但是,我需要首先运行我的gradle命令来构buildJAR,但是我不希望所有gradle使用的东西都在结果泊坞窗图像中。

这是我目前的DockerFile:

 RUN apt-get update && apt-get install -y openjdk-7-jdk COPY . / RUN ./gradlew shadowJar CMD ["java", "-jar", "service/build/libs/service.jar", "server", "service/service.yml"] 

你可以看到,我必须首先COPY所有东西,这样我才能运行./gradlew (否则它表示无法find该命令)。 但最终,我所需要的只是service.jarservice.yml文件。

我可能错过了一些东西,但是如何在./gradlew构build步骤中使所有的东西都可用,但只有结果映像包含service.jarservice.yml

build立一个图像的工作如下。

… docker build命令将使用任何包含Dockerfile作为构build上下文(包括其所有子目录)的目录。 在构build映像之前,构build上下文将被发送到Docker守护进程,这意味着如果使用/作为源存储库,硬盘的全部内容将被发送到守护进程。

请参阅https://docs.docker.com/reference/builder/

我看不到你想要的东西。 有两个选项:

  1. 拥有图像内的所有构build依赖关系,并在容器内部构buildJAR文件。 这膨胀了你的形象。

  2. 我build议单独构build你的JAR,并在构build时ADD可执行文件和configuration文件。 这意味着所有的构build依赖项必须在您的开发环境中可用,但是您的映像尽可能小。

Docker引入了所谓的“多阶段构build”。 有了它们,你可以避免在图像中产生不必要的文件。 你的Dockerfile看起来像这样:

 FROM ubuntu AS build COPY . /src # run your build FROM ubuntu RUN mkdir -p /dist/ COPY --from=build /src/my.object /dist/ 

原则很简单。 在第一个FROM你命名你的构build。 在第二个FROM您可以使用COPY --from= -parameter将文件从第一个版本复制到第二个。 第二个版本是稍后产生可用映像的版本。

有关更多信息: https : //docs.docker.com/engine/userguide/eng-image/multistage-build/#use-multi-stage-builds

你可以这样做:

 FROM java:7 COPY . /sourcecode WORKDIR /sourcecode RUN ./gradlew shadowJar && rm -rf /sourcecode WORKDIR / CMD ["java", "-jar", "service/build/libs/service.jar", "server", "service/service.yml"] 

这使用Docker官方的java镜像( 请参阅回购 )。

RUN行应该创build你的service.jar ,然后在创build图层之前删除所有你已经COPY的源代码,所以源代码不会成为最终图像的一部分。 我假设gradlew也将复制/安装到/ service / build / libs,否则你应该添加该步骤。