Java 如何dockerize Maven 项目?以及有多少方法可以实现?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/27767264/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to dockerize maven project? and how many ways to accomplish it?
提问by Yashon Lin
I am new to Docker, and don't know how to run a java project with maven even though I have read many documents and tried many methods.
我是 Docker 的新手,即使我阅读了很多文档并尝试了很多方法,也不知道如何使用 maven 运行 java 项目。
- Should I build the image using
Dockerfile
? - What is the commands like when it is to run the maven project in the host with
Dockerfile
?
- 我应该使用构建图像
Dockerfile
吗? - 在主机中运行 maven 项目时的命令是
Dockerfile
什么?
采纳答案by Mark O'Connor
Working example.
工作示例。
This is not a spring boot tutorial. It's the updated answer to a question on how to run a Maven build within a Docker container.
这不是 Spring Boot 教程。这是关于如何在 Docker 容器中运行 Maven 构建的问题的更新答案。
Question originally posted 4 years ago.
问题最初发布于 4 年前。
1. Generate an application
1. 生成应用
Use the spring initializer to generate a demo app
使用 spring 初始化程序生成演示应用程序
Extract the zip archive locally
在本地提取 zip 存档
2. Create a Dockerfile
2. 创建一个 Dockerfile
#
# Build stage
#
FROM maven:3.6.0-jdk-11-slim AS build
COPY src /home/app/src
COPY pom.xml /home/app
RUN mvn -f /home/app/pom.xml clean package
#
# Package stage
#
FROM openjdk:11-jre-slim
COPY --from=build /home/app/target/demo-0.0.1-SNAPSHOT.jar /usr/local/lib/demo.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","/usr/local/lib/demo.jar"]
Note
笔记
- This example uses a multi-stage build. The first stage is used to build the code. The second stage only contains the built jar and a JRE to run it (note how jar is copied between stages).
- 此示例使用多阶段构建。第一阶段用于构建代码。第二个阶段只包含构建的 jar 和一个 JRE 来运行它(注意 jar 是如何在阶段之间复制的)。
3. Build the image
3. 构建镜像
docker build -t demo .
4. Run the image
4.运行镜像
$ docker run --rm -it demo:latest
. ____ _ __ _ _
/\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.1.3.RELEASE)
2019-02-22 17:18:57.835 INFO 1 --- [ main] com.example.demo.DemoApplication : Starting DemoApplication v0.0.1-SNAPSHOT on f4e67677c9a9 with PID 1 (/usr/local/bin/demo.jar started by root in /)
2019-02-22 17:18:57.837 INFO 1 --- [ main] com.example.demo.DemoApplication : No active profile set, falling back to default profiles: default
2019-02-22 17:18:58.294 INFO 1 --- [ main] com.example.demo.DemoApplication : Started DemoApplication in 0.711 seconds (JVM running for 1.035)
Misc
杂项
Read the Docker hub documentation on how the Maven build can be optimized to use a local repository to cache jars.
阅读 Docker 中心文档,了解如何优化 Maven 构建以使用本地存储库来缓存 jar。
Update (2019-02-07)
更新 (2019-02-07)
This question is now 4 years old and in that time it's fair to say building application using Docker has undergone significant change.
这个问题现在已经有 4 年了,在那个时候可以说使用 Docker 构建应用程序已经发生了重大变化。
Option 1: Multi-stage build
选项 1:多阶段构建
This new style enables you to create more light-weight images that don't encapsulate your build tools and source code.
这种新风格使您能够创建不封装构建工具和源代码的更轻量级的图像。
The example here again uses the official mavenbase image to run first stage of the build using a desired version of Maven. The second part of the file defines how the built jar is assembled into the final output image.
此处的示例再次使用官方 Maven基础映像,使用所需版本的 Maven 运行构建的第一阶段。文件的第二部分定义了如何将构建的 jar 组装到最终的输出图像中。
FROM maven:3.5-jdk-8 AS build
COPY src /usr/src/app/src
COPY pom.xml /usr/src/app
RUN mvn -f /usr/src/app/pom.xml clean package
FROM gcr.io/distroless/java
COPY --from=build /usr/src/app/target/helloworld-1.0.0-SNAPSHOT.jar /usr/app/helloworld-1.0.0-SNAPSHOT.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","/usr/app/helloworld-1.0.0-SNAPSHOT.jar"]
Note:
笔记:
- I'm using Google's distrolessbase image, which strives to provide just enough run-time for a java app.
- 我正在使用 Google 的distroless基础映像,它努力为 Java 应用程序提供足够的运行时间。
Option 2: Jib
选项 2:吊臂
I haven't used this approach but seems worthy of investigation as it enables you to build images without having to create nasty things like Dockerfiles :-)
我没有使用过这种方法,但似乎值得研究,因为它使您能够构建图像而无需创建令人讨厌的东西,例如 Dockerfiles :-)
https://github.com/GoogleContainerTools/jib
https://github.com/GoogleContainerTools/jib
The project has a Maven pluginwhich integrates the packaging of your code directly into your Maven workflow.
该项目有一个Maven 插件,可将您的代码打包直接集成到您的 Maven 工作流程中。
Original answer (Included for completeness, but written ages ago)
原始答案(包括完整性,但写在很久以前)
Try using the new official images, there's one for Maven
尝试使用新的官方镜像,Maven 有一个
https://registry.hub.docker.com/_/maven/
https://registry.hub.docker.com/_/maven/
The image can be used to run Maven at build time to create a compiled application or, as in the following examples, to run a Maven build within a container.
该映像可用于在构建时运行 Maven 以创建已编译的应用程序,或者如下例所示,在容器内运行 Maven 构建。
Example 1 - Maven running within a container
示例 1 - Maven 在容器中运行
The following command runs your Maven build inside a container:
以下命令在容器内运行您的 Maven 构建:
docker run -it --rm \
-v "$(pwd)":/opt/maven \
-w /opt/maven \
maven:3.2-jdk-7 \
mvn clean install
Notes:
笔记:
- The neat thing about this approach is that all software is installed and running within the container. Only need docker on the host machine.
- See Dockerfile for this version
- 这种方法的巧妙之处在于所有软件都在容器内安装和运行。只需要主机上的docker。
- 请参阅此版本的 Dockerfile
Example 2 - Use Nexus to cache files
示例 2 - 使用 Nexus 缓存文件
Run the Nexus container
运行 Nexus 容器
docker run -d -p 8081:8081 --name nexus sonatype/nexus
Create a "settings.xml" file:
创建一个“settings.xml”文件:
<settings>
<mirrors>
<mirror>
<id>nexus</id>
<mirrorOf>*</mirrorOf>
<url>http://nexus:8081/content/groups/public/</url>
</mirror>
</mirrors>
</settings>
Now run Maven linking to the nexus container, so that dependencies will be cached
现在运行 Maven 链接到 nexus 容器,以便缓存依赖项
docker run -it --rm \
-v "$(pwd)":/opt/maven \
-w /opt/maven \
--link nexus:nexus \
maven:3.2-jdk-7 \
mvn -s settings.xml clean install
Notes:
笔记:
- An advantage of running Nexus in the background is that other 3rd party repositories can be managed via the admin URL transparently to the Maven builds running in local containers.
- 在后台运行 Nexus 的一个优势是,可以通过管理 URL 对其他 3rd 方存储库透明地管理本地容器中运行的 Maven 构建。
回答by Matteo Pacini
As a rule of thumb, you should build a fat JARusing Maven (a JAR that contains both your code and all dependencies).
根据经验,您应该使用 Maven(一个包含您的代码和所有依赖项的 JAR)构建一个胖 JAR。
Then you can write a Dockerfilethat matches your requirements (if you can build a fat JAR you would only need a base os, like CentOS, and the JVM).
然后您可以编写一个符合您要求的Dockerfile(如果您可以构建一个胖 JAR,您将只需要一个基本操作系统,如 CentOS 和 JVM)。
This is what I use for a Scala app (which is Java-based).
这是我用于 Scala 应用程序(基于 Java)的内容。
FROM centos:centos7
# Prerequisites.
RUN yum -y update
RUN yum -y install wget tar
# Oracle Java 7
WORKDIR /opt
RUN wget --no-cookies --no-check-certificate --header "Cookie: gpw_e24=http%3A%2F%2Fwww.oracle.com%2F; oraclelicense=accept-securebackup-cookie" http://download.oracle.com/otn-pub/java/jdk/7u71-b14/server-jre-7u71-linux-x64.tar.gz
RUN tar xzf server-jre-7u71-linux-x64.tar.gz
RUN rm -rf server-jre-7u71-linux-x64.tar.gz
RUN alternatives --install /usr/bin/java java /opt/jdk1.7.0_71/bin/java 1
# App
USER daemon
# This copies to local fat jar inside the image
ADD /local/path/to/packaged/app/appname.jar /app/appname.jar
# What to run when the container starts
ENTRYPOINT [ "java", "-jar", "/app/appname.jar" ]
# Ports used by the app
EXPOSE 5000
This creates a CentOS-based image with Java7. When started, it will execute your app jar.
这将使用 Java7 创建一个基于 CentOS 的映像。启动时,它将执行您的应用程序 jar。
The best way to deploy it is via the Docker Registry, it's like a Github for Docker images.
部署它的最佳方式是通过 Docker Registry,它就像 Docker 镜像的 Github。
You can build an image like this:
您可以构建这样的图像:
# current dir must contain the Dockerfile
docker build -t username/projectname:tagname .
You can then push an image in this way:
然后,您可以通过这种方式推送图像:
docker push username/projectname # this pushes all tags
Once the image is on the Docker Registry, you can pull it from anywhere in the world and run it.
一旦镜像在 Docker Registry 上,您就可以从世界任何地方拉取它并运行它。
See Docker User Guidefor more informations.
有关更多信息,请参阅Docker 用户指南。
Something to keep in mind:
要记住的事情:
You could also pull your repository inside an image and build the jar as part of the container execution, but it's not a good approach, as the code could change and you might end up using a different version of the app without notice.
您也可以将存储库拉入映像并构建 jar 作为容器执行的一部分,但这不是一个好方法,因为代码可能会更改,并且您最终可能会在没有通知的情况下使用不同版本的应用程序。
Building a fat jar removes this issue.
构建一个胖罐子消除了这个问题。
回答by Riddhi Gohil
There may be many ways.. But I implemented by following two ways
可能有很多方法..但我通过以下两种方式实现
Given example is of maven project.
给出的例子是 maven 项目。
1. Using Dockerfile in maven project
1.在maven项目中使用Dockerfile
Use the following file structure:
使用以下文件结构:
Demo
└── src
| ├── main
| │ ├── java
| │ └── org
| │ └── demo
| │ └── Application.java
| │
| └── test
|
├──── Dockerfile
├──── pom.xml
And update the Dockerfile as:
并将 Dockerfile 更新为:
FROM java:8
EXPOSE 8080
ADD /target/demo.jar demo.jar
ENTRYPOINT ["java","-jar","demo.jar"]
Navigate to the project folder and type following command you will be ab le to create image and run that image:
导航到项目文件夹并键入以下命令,您将能够创建图像并运行该图像:
$ mvn clean
$ mvn install
$ docker build -f Dockerfile -t springdemo .
$ docker run -p 8080:8080 -t springdemo
Get video at Spring Boot with Docker
2. Using Maven plugins
2. 使用 Maven 插件
Add given maven plugin in pom.xml
添加给定的 maven 插件 pom.xml
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.4.5</version>
<configuration>
<imageName>springdocker</imageName>
<baseImage>java</baseImage>
<entryPoint>["java", "-jar", "/${project.build.finalName}.jar"]</entryPoint>
<resources>
<resource>
<targetPath>/</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
</configuration>
</plugin>
Navigate to the project folder and type following command you will be able to create image and run that image:
导航到项目文件夹并键入以下命令,您将能够创建图像并运行该图像:
$ mvn clean package docker:build
$ docker images
$ docker run -p 8080:8080 -t <image name>
In first example we are creating Dockerfile and providing base image and adding jar an so, after doing that we will run docker command to build an image with specific name and then run that image..
在第一个示例中,我们正在创建 Dockerfile 并提供基础映像并添加 jar 和 so,然后我们将运行 docker 命令以构建具有特定名称的映像,然后运行该映像。
Whereas in second example we are using maven plugin in which we providing baseImage
and imageName
so we don't need to create Dockerfile here.. after packaging maven project we will get the docker image and we just need to run that image..
而在第二个示例中,我们使用的是我们提供的 maven 插件baseImage
,imageName
因此我们不需要在此处创建 Dockerfile。
回答by davidxxx
Here is my contribution.
I will not try to list all tools/libraries/plugins that exist to take advantage of Docker with Maven. Some answers have already done it.
instead of, I will focus on applications typology and the Dockerfile way.Dockerfile
is really a simple and important concept of Docker (all known/public images rely on that) and I think that trying to avoid understanding and using Dockerfile
s is not necessarily the better way to enter in the Docker world.
这是我的贡献。
我不会尝试列出所有现有的工具/库/插件来利用 Docker 和 Maven。有些答案已经做到了。
相反,我将专注于应用程序类型和 Dockerfile 方式。Dockerfile
确实是 Docker 的一个简单而重要的概念(所有已知/公共图像都依赖于此),我认为尝试避免理解和使用Dockerfile
s 不一定是进入 Docker 世界的更好方法。
Dockerizing an application depends on the application itself and the goal to reach
Dockerizing 应用程序取决于应用程序本身和要达到的目标
1) For applications that we want to go on to run them on installed/standalone Java server (Tomcat, JBoss, etc...)
1) 对于我们希望继续在已安装/独立的 Java 服务器(Tomcat、JBoss 等...)上运行它们的应用程序
The road is harder and that is not the ideal targetbecause that adds complexity (we have to manage/maintain the server) and it is less scalable and less fast than embedded servers in terms of build/deploy/undeploy.
But for legacy applications, that may considered as a first step.
Generally, the idea here is to define a Docker image for the server and to define an image per application to deploy.
The docker images for the applications produce the expected WAR/EAR but these are not executed as container and the image for the server application deploys the components produced by these images as deployed applications.
For huge applications (millions of line of codes) with a lot of legacy stuffs, and so hard to migrate to a full spring boot embedded solution, that is really a nice improvement.
I will not detail more that approach since that is for minor use cases of Docker but I wanted to expose the overall idea of that approach because I think that for developers facing to these complex cases, it is great to know that some doors are opened to integrate Docker.
这条路更艰难,这不是理想的目标,因为这增加了复杂性(我们必须管理/维护服务器),并且在构建/部署/取消部署方面,它的可扩展性和速度不如嵌入式服务器。
但对于遗留应用程序,这可能被视为第一步。
通常,这里的想法是为服务器定义一个 Docker 镜像,并为每个要部署的应用程序定义一个镜像。
应用程序的 docker 映像生成预期的 WAR/EAR,但它们不会作为容器执行,服务器应用程序的映像将这些映像生成的组件部署为已部署的应用程序。
对于具有大量遗留内容的大型应用程序(数百万行代码),并且很难迁移到完整的 Spring Boot 嵌入式解决方案,这确实是一个很好的改进。
我不会详细说明这种方法,因为这是针对 Docker 的次要用例,但我想公开这种方法的总体思路,因为我认为对于面临这些复杂情况的开发人员来说,很高兴知道有些门可以集成 Docker。
2) For applications that embed/bootstrap the server themselves (Spring Boot with server embedded : Tomcat, Netty, Jetty...)
2)对于嵌入/引导服务器本身的应用程序(嵌入服务器的Spring Boot:Tomcat,Netty,Jetty ...)
That is the ideal target with Docker.
I specified Spring Boot because that is a really nice framework to do that and that has also a very high level of maintainability but in theory we could use any other Java way to achieve that.
Generally, the idea here is to define a Docker image per application to deploy.
The docker images for the applications produce a JAR or a set of JAR/classes/configuration files and these start a JVM with the application (java command) when we create and start a container from these images.
For new applications or applications not too complex to migrate, that way has to be favored over standalone servers because that is the standard way and the most efficient way of using containers.
I will detail that approach.
这是 Docker 的理想目标。我指定 Spring Boot 是因为这是一个非常好的框架,并且具有非常高的可维护性,但理论上我们可以使用任何其他 Java 方式来实现这一点。
通常,这里的想法是为每个要部署的应用程序定义一个 Docker 映像。
应用程序的 docker 映像生成一个 JAR 或一组 JAR/类/配置文件,当我们从这些映像创建和启动容器时,这些文件会使用应用程序(java 命令)启动 JVM。
对于新的应用程序或不太复杂的应用程序迁移,这种方式必须优于独立服务器,因为这是使用容器的标准方式和最有效的方式。
我将详细介绍这种方法。
Dockerizing a maven application
Docker 化一个 Maven 应用程序
1) Without Spring Boot
1) 没有 Spring Boot
The idea is to create a fat jar with Maven (the maven assembly plugin and the maven shade plugin help for that) that contains both the compiled classes of the application and needed maven dependencies.
Then we can identify two cases :
这个想法是用 Maven 创建一个胖 jar(maven 程序集插件和 maven shade 插件帮助),其中包含应用程序的编译类和所需的 maven 依赖项。
然后我们可以确定两种情况:
if the application is a desktop or autonomous application (that doesn't need to be deployed on a server) : we could specify as
CMD/ENTRYPOINT
in theDockerfile
the java execution of the application :java -cp .:/fooPath/* -jar myJar
if the application is a server application, for example Tomcat, the idea is the same : to get a fat jar of the application and to run a JVM in the
CMD/ENTRYPOINT
. But here with an important difference : we need to include some logic and specific libraries (org.apache.tomcat.embed
libraries and some others) that starts the embedded server when the main application is started.
We have a comprehensive guide on the heroku website.
For the first case (autonomous application), that is a straight and efficient way to use Docker.
For the second case (server application), that works but that is not straight, may be error prone and is not a very extensible model because you don't place your application in the frame of a mature framework such as Spring Boot that does many of these things for you and also provides a high level of extension.
But that has a advantage : you have a high level of freedom because you use directly the embedded Tomcat API.
如果应用程序是一个桌面或自主应用程序(即不需要被部署在服务器上):我们可以指定为
CMD/ENTRYPOINT
在Dockerfile
应用程序的Java执行:java -cp .:/fooPath/* -jar myJar
如果应用程序是服务器应用程序,例如 Tomcat,想法是相同的:获取应用程序的胖 jar 并在
CMD/ENTRYPOINT
. 但是这里有一个重要的区别:我们需要包含一些逻辑和特定的库(org.apache.tomcat.embed
库和其他一些库)在主应用程序启动时启动嵌入式服务器。
我们在 heroku 网站上有一个综合指南。
对于第一种情况(自治应用程序),这是使用 Docker 的一种直接而有效的方式。
对于第二种情况(服务器应用程序),它可以工作但不是直接的,可能容易出错并且不是一个非常可扩展的模型,因为您没有将您的应用程序置于成熟框架(例如 Spring Boot)的框架中,该框架可以执行许多操作这些东西也为你提供了高水平的扩展。
但这有一个优点:您拥有高度的自由度,因为您直接使用嵌入式 Tomcat API。
2) With Spring Boot
2) 使用 Spring Boot
At last, here we go.
That is both simple, efficient and very well documented.
There are really several approaches to make a Maven/Spring Boot application to run on Docker.
Exposing all of them would be long and maybe boring.
The best choice depends on your requirement.
But whatever the way, the build strategy in terms of docker layers looks like the same.
We want to use a multi stage build : one relying on Maven for the dependency resolution and for build and another one relying on JDK or JRE to start the application.
最后,我们走了。
这既简单又高效,而且有据可查。
确实有几种方法可以使 Maven/Spring Boot 应用程序在 Docker 上运行。
暴露所有这些会很长,而且可能很无聊。
最佳选择取决于您的要求。
但无论如何,Docker 层的构建策略看起来是一样的。
我们想使用多阶段构建:一个依赖 Maven 进行依赖解析和构建,另一个依赖 JDK 或 JRE 来启动应用程序。
Build stage (Maven image) :
构建阶段(Maven 镜像):
- pom copy to the image
- dependencies andplugins downloads.
About that,mvn dependency:resolve-plugins
chained tomvn dependency:resolve
may do the job but not always.
Why ? Because these plugins and thepackage
execution to package the fat jar may rely on different artifacts/plugins and even for a same artifact/plugin, these may still pull a different version. So a safer approach while potentially slower is resolving dependencies by executing exactly themvn
command used to package the application (which will pull exactly dependencies that you are need) but by skipping the source compilation and by deleting the target folder to make the processing faster and to prevent any undesirable layer change detection for that step. - source code copy to the image
- package the application
- pom 复制到图像
- 依赖项和插件下载。
关于这一点,mvn dependency:resolve-plugins
链接到mvn dependency:resolve
可能会完成这项工作,但并非总是如此。
为什么 ?因为这些插件和package
打包 fat jar的执行可能依赖于不同的 artifacts/plugins,甚至对于相同的 artifact/plugin,它们仍然可能会拉不同的版本。因此,一种更安全但可能较慢的方法是通过准确mvn
执行用于打包应用程序的命令(它将准确提取您需要的依赖项)来解决依赖项,但跳过源编译并删除目标文件夹以加快处理速度并防止该步骤的任何不受欢迎的层变化检测。 - 源代码复制到图像
- 打包应用程序
Run stage (JDK or JRE image) :
运行阶段(JDK 或 JRE 映像):
- copy the jar from the previous stage
- 复制上一阶段的 jar
Here two examples.
这里有两个例子。
a) A simple way without cache for downloaded maven dependencies
a) 一种无需缓存下载的 Maven 依赖项的简单方法
Dockerfile :
Dockerfile :
########Maven build stage########
FROM maven:3.6-jdk-11 as maven_build
WORKDIR /app
#copy pom
COPY pom.xml .
#resolve maven dependencies
RUN mvn clean package -Dmaven.test.skip -Dmaven.main.skip -Dspring-boot.repackage.skip && rm -r target/
#copy source
COPY src ./src
# build the app (no dependency download here)
RUN mvn clean package -Dmaven.test.skip
# split the built app into multiple layers to improve layer rebuild
RUN mkdir -p target/docker-packaging && cd target/docker-packaging && jar -xf ../my-app*.jar
########JRE run stage########
FROM openjdk:11.0-jre
WORKDIR /app
#copy built app layer by layer
ARG DOCKER_PACKAGING_DIR=/app/target/docker-packaging
COPY --from=maven_build ${DOCKER_PACKAGING_DIR}/BOOT-INF/lib /app/lib
COPY --from=maven_build ${DOCKER_PACKAGING_DIR}/BOOT-INF/classes /app/classes
COPY --from=maven_build ${DOCKER_PACKAGING_DIR}/META-INF /app/META-INF
#run the app
CMD java -cp .:classes:lib/* \
-Djava.security.egd=file:/dev/./urandom \
foo.bar.MySpringBootApplication
Drawback of that solution ? Any changes in the pom.xml means re-creates the whole layer that download and stores the maven dependencies. That is generally not acceptable for applications with many dependencies (and Spring Boot pulls many dependencies), overall if you don't use a maven repository manager during the image build.
该解决方案的缺点?pom.xml 中的任何更改都意味着重新创建下载和存储 maven 依赖项的整个层。对于具有许多依赖项(并且 Spring Boot 拉取许多依赖项)的应用程序,这通常是不可接受的,总体而言,如果您在映像构建期间不使用 Maven 存储库管理器。
b) A more efficient way with cache for maven dependencies downloaded
b) 一种更有效的方式,对下载的 Maven 依赖项进行缓存
The approach is here the same but maven dependencies downloads that are cached in the docker builder cache.
The cache operation relies on buildkit (experimental api of docker).
To enable buildkit, the env variable DOCKER_BUILDKIT=1 has to be set (you can do that where you want : .bashrc, command line, docker daemon json file...).
此处的方法相同,但 Maven 依赖项下载缓存在 docker builder 缓存中。
缓存操作依赖于buildkit(docker的实验性api)。
要启用 buildkit,必须设置环境变量 DOCKER_BUILDKIT=1(您可以在需要的地方执行此操作:.bashrc、命令行、docker daemon json 文件...)。
Dockerfile :
Dockerfile :
# syntax=docker/dockerfile:experimental
########Maven build stage########
FROM maven:3.6-jdk-11 as maven_build
WORKDIR /app
#copy pom
COPY pom.xml .
#copy source
COPY src ./src
# build the app (no dependency download here)
RUN --mount=type=cache,target=/root/.m2 mvn clean package -Dmaven.test.skip
# split the built app into multiple layers to improve layer rebuild
RUN mkdir -p target/docker-packaging && cd target/docker-packaging && jar -xf ../my-app*.jar
########JRE run stage########
FROM openjdk:11.0-jre
WORKDIR /app
#copy built app layer by layer
ARG DOCKER_PACKAGING_DIR=/app/target/docker-packaging
COPY --from=maven_build ${DOCKER_PACKAGING_DIR}/BOOT-INF/lib /app/lib
COPY --from=maven_build ${DOCKER_PACKAGING_DIR}/BOOT-INF/classes /app/classes
COPY --from=maven_build ${DOCKER_PACKAGING_DIR}/META-INF /app/META-INF
#run the app
CMD java -cp .:classes:lib/* \
-Djava.security.egd=file:/dev/./urandom \
foo.bar.MySpringBootApplication