4

Dockerfile:

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 build 失败并出现错误:目标文件夹不存在
下面的 dockerfile 完美运行:

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 更改为 RUN 即可解决此问题。为什么会这样?我认为在间歇性容器中,cmd 会执行,这应该使两个命令等效吗?

4

1 回答 1

6

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

CMD然而,指令不会在构建时调用,它仅适用于运行时,如官方文档中明确说明的那样:

CMD 的主要目的是为正在执行的容器提供默认值。

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

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

RUN 指令将在当前映像之上的新层中执行任何命令并提交结果。生成的提交图像将用于 Dockerfile 中的下一步。

现在应该清楚为什么多阶段构建RUN在与CMD指令相反使用时会成功完成。

您的困惑始于错误地假设以下情况为真:

我认为在间歇性容器中,cmd 会执行,这应该使两个命令等效吗?

于 2020-07-20T11:57:47.017 回答