英文:
Running Maven test in Docker container
问题
我有一个在Docker容器中的Spring Boot应用程序,当我运行执行测试的命令时,我看到应用程序正确启动,但没有执行测试。似乎mvn test
被完全忽略了。
以下是我的Docker命令:
docker build -t cygnetops/react-test -f Dockerfile.dev .
docker run cygnetops/react-test mvn test
Dockerfile.dev
FROM eclipse-temurin:17-jdk-alpine
VOLUME /tmp
ADD /target/demoCI-CD-0.0.1-SNAPSHOT.jar app.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
EXPOSE 5000
英文:
I have a Spring boot application in a Docker container and when I run the command to execute tests I see that the app starts correctly but there is no test executed. Looks like the mvn test
is completely ignored.
Below my docker commands:
docker build -t cygnetops/react-test -f Dockerfile.dev .
docker run cygnetops/react-test mvn test
Dockerfile.dev
FROM eclipse-temurin:17-jdk-alpine
VOLUME /tmp
ADD /target/demoCI-CD-0.0.1-SNAPSHOT.jar app.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
EXPOSE 5000
答案1
得分: 1
入口点和命令在Docker容器中协同工作,如果您指定一个入口点,您的命令将作为参数传递给入口点,如果该入口点对传递给它的参数不执行任何操作,那么您观察到的行为是完全正常的。
文档的“理解CMD和ENTRYPOINT的交互”章节提供了一张漂亮的表格,深入解释了它们之间的交互。
为了从该镜像运行测试,您可以在运行容器时覆盖入口点:
docker run --entrypoint "" cygnetops/react-test mvn test
注意:
- 您还必须安装Maven,因为它不是您基础镜像的一部分
- 正如您指出的,您还需要Java项目的POM和文件以便运行测试,因此您需要将这些源文件复制到镜像中
因此,在您的 Dockerfile 中添加以下行:
COPY . .
RUN apk add --no-cache maven
另一方面,如果您希望两者都能正常工作,您将不得不编写自己的入口点并对传递的命令进行处理。
这里是一个例子:
entrypoint.sh,应该位于与您的 Dockerfile 相同的级别:
#!/usr/bin/env sh
exec "$@" # 执行作为参数传递的内容
java -Djava.security.egd=file:/dev/./urandom -jar /app.jar
然后,在您的 Dockerfile 中:
FROM eclipse-temurin:17-jdk-alpine
VOLUME /tmp
RUN apk add --no-cache maven
COPY . .
COPY /target/demoCI-CD-0.0.1-SNAPSHOT.jar app.jar
COPY entrypoint.sh /usr/local/bin/
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 5000
英文:
Entrypoints and commands are working together in a Docker container, if you specify an entrypoint, your command will be passed as an argument to the entrypoint, and if that entrypoint does nothing with the arguments passed to it, then the behaviour you are observing it totally normal.
The chapter "Understand how CMD and ENTRYPOINT interact" of the documentation provides a nice table explaining in depth how they interact.
In order to run you tests from that image, you could override the entrypoint when running you container:
docker run --entrypoint "" cygnetops/react-test mvn test
Note:
- you will also have to install Maven, as it is not part of your base image
- as you pointed, you will also need the POM and files of the Java project in order to run the tests, so you need to copy those sources in the image
So, add, in your Dockerfile, the lines:
COPY . .
RUN apk add --no-cache maven
If you want both to work, on the other hand, you will have to write your own entrypoint and make something from the command passed as arguments.
Here is an example:
entrypoint.sh, should be located at the same level as your Dockerfile:
#!/usr/bin/env sh
exec "$@" # execute what is passed as argument
java -Djava.security.egd=file:/dev/./urandom -jar /app.jar
Then, for your Dockerfile
FROM eclipse-temurin:17-jdk-alpine
VOLUME /tmp
RUN apk add --no-cache maven
COPY . .
COPY /target/demoCI-CD-0.0.1-SNAPSHOT.jar app.jar
COPY entrypoint.sh /usr/local/bin/
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 5000
答案2
得分: 0
也许更好的解决方案是创建一个Docker文件,而不是运行纯Java脚本。例如,创建一个名为runner.sh的文件,内容如下:
#!/bin/bash
CMD="java -jar app.jar"
$CMD &
SERVICE_PID=$!
mvn test
wait "$SERVICE_PID"
然后,这将是您的Docker文件:
FROM maven:3.9.0-eclipse-temurin-11-alpine
COPY . .
RUN mvn install
COPY runner.sh /scripts/runner.sh
RUN ["chmod", "+x", "/scripts/runner.sh"]
ENTRYPOINT ["/scripts/runner.sh"]
英文:
Maybe a better solution is to create a docker file that runs a script instead of plain java. for example create a runner.sh file as follow:
#!/bin/bash
CMD="java -jar app.jar"
$CMD &
SERVICE_PID=$!
mvn test
wait "$SERVICE_PID"
and this will be your dockerfile
FROM maven:3.9.0-eclipse-temurin-11-alpine
COPY . .
RUN mvn install
COPY runner.sh /scripts/runner.sh
RUN ["chmod", "+x", "/scripts/runner.sh"]
ENTRYPOINT ["/scripts/runner.sh"]
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论