简体   繁体   English

Java docker文件。 生成并测试还是只运行jar文件?

[英]Java docker file. Build and test or just run jar file?

I'm thinking this in a CI pipeline where I should first build and test my app and the result should be a docker image. 我在CI管道中正在考虑这一点,我应该首先构建和测试我的应用,结果应该是docker映像。

I'm wondering if it's more common to build on the build server using the build environment and then running tests. 我想知道是否更常见的是使用构建环境在构建服务器上进行构建然后运行测试。 Maybe using a build script for this. 也许为此使用构建脚本。 And lastly just add the jar file to the Docker container produced using COPY and then have Entrypoint java -jar .jar. 最后,只需将jar文件添加到使用COPY生成的Docker容器中,然后使用Entrypoint java -jar .jar。 So keep the Dockerfile very small, and have testing and building outside the container. 因此,请保持Dockerfile很小,并在容器外部进行测试和构建。

A bit like this: 有点像这样:

FROM openjdk:8-jre-alpine
CMD java ${JAVA_OPTS} -jar *.jar
COPY build/libs/*.jar .

Or if I should add all the source code to the container, build it and then run tests inside the container and then having the Entrypoint (as before) running the jar file that was produced? 或者,如果我应该将所有源代码添加到容器中,请构建它,然后在容器中运行测试,然后让Entrypoint(如前所述)运行所生成的jar文件? So keeping everything in the Dockerfile? 那么将所有内容都保留在Dockerfile中吗? Maybe doing some cleanup also, removing the source code 也许还要进行一些清理,删除源代码

This doesn't really have to be Java I guess, the same question applies to all languages 我猜这不一定是Java,同样的问题适用于所有语言

You build and test the app in the so called build docker image, with the JDK and all tools you need for that purpose. 您可以使用JDK和为此目的所需的所有工具在所谓的构建docker映像中构建和测试应用程序。 When you are done and happy, you extract the jar/war as an artifact into your CI/CD pipeline and then, when you consider it production ready, you build a production docker image and put the artifact inside, where you only have a JRE/Tomcat (whatever you need for production only) - no dev tools, not compile tools nothing - as small and sleek and simple as possible. 完成并感到高兴后,您将jar / war作为工件提取到CI / CD管道中,然后,当您考虑将其投入生产时,就可以构建生产docker映像并将其放入内部,其中只有JRE / Tomcat(只需要生产用的任何东西)-无需开发工具,而无需编译工具-尽可能小巧,时尚。

So you basically always have 2 images per app at least, one for building it and one for running it in production. 因此,每个应用程序基本上总是至少有2张图像,其中一张用于构建,另一张用于在生产环境中运行。 Mixing both is very bad practice and will lead to issues sooner or later. 混合使用是非常不好的做法,迟早会导致问题。

Building on the host is even worse, since you do not use clean environments this way, which is more or less one of the key gains with docker - and you cannot reproduce the build locally easily. 在主机上构建甚至更糟,因为您不以这种方式使用干净的环境,这或多或少是docker的主要优势之一-而且您无法在本地轻松地复制构建。

Optimizing the container build 优化容器构建

Historically one was forced to run Docker twice in order to create a docker image that did not contain the source code (and the software used to create the binary) For example see 过去,为了创建一个不包含源代码(以及用于创建二进制文件的软件)的Docker映像,一个被迫运行Docker两次。例如,请参阅

Now, Docker supports a new multistage build capability: 现在,Docker支持新的多阶段构建功能:

This enables Docker to build a container with an image containing the build tools but output an image with only the runtime dependencies. 这使Docker可以使用包含构建工具的映像来构建容器,但仅输出具有运行时依赖项的映像。 The following example demonstrates this concept, note how the jar is copied from target directory of the first build phase 以下示例演示了此概念,请注意如何从第一个构建阶段的目标目录复制jar

FROM maven:3.3-jdk-8-onbuild 

FROM java:8
COPY --from=0 /usr/src/app/target/demo-1.0-SNAPSHOT.jar /opt/demo.jar
CMD ["java","-jar","/opt/demo.jar"]

The resultant image does not contain the maven, only java and the built jar. 生成的图像不包含Maven,仅包含Java和内置的jar。

Testing 测试中

Assuming we're not talking about unit tests (which can be run locally) an integration test requires that the code first be deployed. 假设我们不是在谈论单元测试(可以在本地运行),那么集成测试需要首先部署代码。 The answer in this case is highly dependent on how you deploy your containerized Java application. 在这种情况下,答案很大程度上取决于您如何部署容器化Java应用程序。

For example if you're using Kubernetes or Openshift one option is to use the Fabric8 plugin to deploy the code before running your test phase in Maven. 例如,如果您使用的是Kubernetes或Openshift,则一种选择是使用Fabric8插件在Maven中运行测试阶段之前部署代码。

To solve this problem, I borrowed the SoC (Separation of Concerns) design principle from computer science and decided to go with the two docker image approach: one to build/test the app and one to run it. 为了解决这个问题,我借鉴了计算机科学的SoC(关注分离)设计原理,并决定采用两种docker image方法:一种用于构建/测试应用程序,另一种用于运行应用程序。 Another benefit of keeping the processes separate is reducing the chance of unintended behavior which will simplify maintenance and regression testing. 将流程分开的另一个好处是减少了意外行为的机会,这将简化维护和回归测试。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 可以运行jar文件。 Maven构建后出现JNI错误。 类路径可以被破坏 - Can run jar file. JNI error after maven build. Classpath can be broken Eclipse,Java,Junit4,我想对 jar 文件进行黑盒测试。 在设置方面需要一点帮助 - Eclipse, Java, Junit4, I want to blackbox test a jar file. Need a little help in setting up 我的Java程序在netbeans中运行,但不会在命令中或通过jar文件运行。 我究竟做错了什么? - My java program runs in netbeans, but will not run in command or through the jar file. What am I doing wrong? 将 Maven 构建步骤添加到 docker 文件中,用于 Java Jar? - Adding Maven build steps into docker file for Java Jar? 如何构建Java Jar文件并在Android设备上运行UIAutomator? - How to build a Java Jar file and run UIAutomator on an Android device? 无法创建 .jar 文件。 使用 gradle 时出错,尤其是 ./gradlew build。 获取 java.lang.IllegalAccessError - Unable to create .jar file. Error while working with gradle, particularly ./gradlew build. getting java.lang.IllegalAccessError JAVA:无法运行jar文件 - JAVA: Unable to run a jar file Java运行jar文件并包含外部jar - Java run jar file & include external jar 如何在Docker容器中使用Docker文件运行jar文件 - How to run jar file using docker file in docker container 从Java文件运行jar文件 - Run a jar file from a java file
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM