Docker 如果我们在 dockerfile 中使用 CMD,多阶段构建会失败

Docker multi-stage build fails if we use CMD in dockerfile

Docker 文件:

FROM maven:3.6.3-openjdk-8 as builder
# Set the working directory.
WORKDIR /usr/src/mymaven
COPY ./ /usr/src/mymaven
CMD [ "mvn" , "clean" , "install" ]

FROM openjdk:8
COPY --from=builder /usr/src/mymaven/target /usr/src/myapp
WORKDIR /usr/src/myapp
CMD ["java", "-jar" , "Backend-0.0.1-SNAPSHOT.jar"]

上面的 docker 构建失败并出现错误: 目标文件夹不存在
以下 docker 文件完美运行:

FROM maven:3.6.3-openjdk-8 as builder
# Set the working directory.
WORKDIR /usr/src/mymaven
COPY ./ /usr/src/mymaven
RUN [ "mvn" , "clean" , "install" ]

FROM openjdk:8
COPY --from=builder /usr/src/mymaven/target /usr/src/myapp
WORKDIR /usr/src/myapp
CMD ["java", "-jar" , "Backend-0.0.1-SNAPSHOT.jar"]

只需将 CMD 更改为 运行 即可解决问题。为什么会这样?我想在间歇性容器中,cmd 会执行,这应该使两个命令等效吧?

在多阶段构建中,您可以复制上一步中的文件。每个步骤都被视为一个单独的私有图像(在多阶段构建的范围内)。

然而,

CMD 指令不会在构建时调用,它仅适用于运行时,如 official docs:

中明确说明

The main purpose of a CMD is to provide defaults for an executing container.

由于您目前正在构建结果图像,CMD 永远不会执行,因此您得到了您所报告的错误。

另一方面,RUN 指令在构建期间执行,使其结果可用于下一步。再次引用 docs:

The RUN instruction will execute any commands in a new layer on top of the current image and commit the results. The resulting committed image will be used for the next step in the Dockerfile.

现在应该清楚为什么在使用 RUN 而不是 CMD 指令时多阶段构建成功完成。

您的困惑源于错误地假设以下内容为真:

I thought in the intermittent container, the cmd would execute which should make both the commands equivalent right?