如何为java应用程序构建docker容器 [英] How to build a docker container for a java app

查看:139
本文介绍了如何为java应用程序构建docker容器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想要做的是为我的Java应用程序构建一个Docker映像,但对于大多数编译语言,以下注意事项应该是正确的。

What I want to do is build a docker image for my Java application but the following considerations should be true for most compiled languages.

在我的构建服务器上,我想为我的应用程序生成一个Docker映像作为可交付项。为此,我必须使用一些构建工具(通常是Gradle,Maven或Ant)编译应用程序,然后将创建的JAR文件添加到docker映像。当我想要Docker的图像只是执行JAR文件时,我当然会从已经安装Java的基本映像开始。

On my build server I want to produce a docker image for my application as the deliverable. For this I have to compile the application using some build tool (typically Gradle, Maven or Ant) and then add the created JAR file to the docker image. As I want the docker image to just execute the JAR file I will of course start from a base image with Java already installed.

在这种情况下,我的构建工具控制整个过程。所以它准备JAR文件,并且在创建JAR之后,它调用Docker来创建映像。这个作用是事先创建JAR,Docker可以忽略创建JAR所需的构建过程。

In this case my build tool controls the whole process. So it prepares the JAR file and after the JAR is created it calls Docker to create the image. This works as the JAR is created beforehand and Docker can be oblivious of the build process needed to create the JAR.

但是我的Dockerfile不再是独立的。这取决于在Docker之外发生的步骤。在我的Docker文件中,我将有一个应该将JAR文件复制到图像的 COPY ADD 语句。当事先未创建jar时,此语句将失败。所以只是执行Dockerfile可能无效。如果您想要使用DockerHub上的自动构建功能来构建使用当前Dockerfile的服务,那么这将成为一个问题。

But my Dockerfile is no longer standalone. It depends on steps to happen outside of Docker for it work. In my Dockerfile I will have a COPY or ADD statement that is supposed to copy the JAR file to the image. This statement will fail when the jar is not created beforehand. So just executing the Dockerfile might not work. This becomes a problem if you want to integrate with services that just build using the present Dockerfile like the auto-build feature on DockerHub.

在这种情况下,创建图像的所有必要步骤都将添加到Docker文件中,以便可以通过执行Docker构建来创建图像。

In this case all necessary steps to create the image are added to the Dockerfile so the image can be created by just executing the Docker build.

这种方法的主要问题是无法添加到Dockerfile中,该命令应该在要创建的docker映像之外执行。这意味着我必须将源代码和我的构建工具添加到docker映像中,并在映像中构建我的JAR文件。这将导致我的图像大于由于所有添加的文件在运行时不必要的。

The main problem with this approach is that there is no way to add to a Dockerfile commands that should be executed outside the docker image being created. This means I have to add my source code and my build tools to the docker image and build my JAR file inside the image. This will result in my image being bigger than it has to be due to all the files added that will be unnecessary at runtime. This will also add extra layers to my image.

正如@ adrian-mouat指出的那样我将添加源,构建应用程序并删除一个RUN语句中的源,我可以避免向Docker映像添加不必要的文件和图层。这将意味着创建一些疯狂的链接命令。

As @adrian-mouat pointed out if I would add the sources, build the application and deleted the sources in one RUN statement I could avoid adding unnecessary files and layers to the Docker image. This would mean creating some insane chained command.

在这种情况下,我们将构建分为两个:首先我们使用我们的构建工具并将其上传到存储库(Maven或Ivy存储库)。然后我们触发一个单独的Docker构建,它只是从存储库中添加JAR文件。

In this case we split our build in two: first we create the JAR file using our build tool and upload it to a repository (Maven or Ivy repository). We then trigger a separate Docker build that just adds the JAR file from the repository.

在我的意见更好的方法是让构建工具控制流程。这将导致一个干净的码头图像,因为图像是我们想要提供的这是重要的。为了避免潜在的不工作的Dockerfile在这个周围应该被创建作为构建的一部分。所以没有人会不小心使用它来启动破碎的构建。

In my opinion the better way would be letting the build tool control the process. This is will result in a clean docker image and as the image is what we want to deliver this is of importance. To avoid having a potentially not working Dockerfile lying around this should be created as part of the build. So no one would accidentally use it to start a broken build.

但是这不允许我与DockerHub集成。

But this will not allow me to integrate with DockerHub.

有没有另一种方法我缺少?

Is there another way I am missing?

推荐答案

Docker注册中心具有可用于创建java容器的 Maven映像

The docker registry hub has a Maven image that can be used to create java containers.

使用这种方法,构建机器不需要预安装Java或Maven,Docker控制整个构建过程。

Using this approach the build machine does not need to have either Java or Maven pre-installed, Docker controls the entire build process.

├── Dockerfile
├── pom.xml
└── src
    ├── main
    │   ├── java
    │   │   └── org
    │   │       └── demo
    │   │           └── App.java
    │   └── resources
    │       └── log4j.properties
    └── test
        └── java
            └── org
                └── demo
                    └── AppTest.java

容器的构建如下:

docker build -t my-maven .

并运行如下:

$ docker run -it --rm my-maven
0    [main] INFO  org.demo.App  - hello world



Dockerfile



Dockerfile

FROM maven:3.3-jdk-8-onbuild
CMD ["java","-jar","/usr/src/app/target/demo-1.0-SNAPSHOT-jar-with-dependencies.jar"]






更新



如果你想优化您的容器以排除源,您可以创建一个仅包含内置jar的Docker文件:


Update

If you wanted to optimize your container to exclude the source you could create a Dockerfile that only includes the built jar:

FROM java:8
ADD target/demo-1.0-SNAPSHOT-jar-with-dependencies.jar /opt/demo/demo-1.0-SNAPSHOT-jar-with-dependencies.jar
CMD ["java","-jar","/opt/demo/demo-1.0-SNAPSHOT-jar-with-dependencies.jar"]

并分两步构建容器:

docker run -it --rm -w /opt/maven \
   -v $PWD:/opt/maven \
   -v $HOME/.m2:/root/.m2 \
   maven:3.3-jdk-8 \
   mvn clean install

docker build -t my-app .

这篇关于如何为java应用程序构建docker容器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆