【问题标题】:Docker multi-stage build fails if we use CMD in dockerfile如果我们在 dockerfile 中使用 CMD,Docker 多阶段构建会失败
【发布时间】:2020-11-09 15:00:42
【问题描述】:

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会执行,这应该使两个命令等效吗?

【问题讨论】:

  • CMD 在构建时不运行任何东西。它只是在您稍后运行容器时设置一个默认命令。
  • “我认为在间歇性容器中,cmd 会执行,这应该使两个命令等效”你有任何链接吗?
  • @Thilo 没有来源只是我的假设

标签: java docker maven dockerfile docker-multi-stage-build


【解决方案1】:

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

CMD 指令在构建时不会被调用,它只适用于运行时,正如official docs 中明确指出的那样:

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

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

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

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

现在应该清楚为什么使用RUNCMD 指令相比,多阶段构建成功完成。

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

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

【讨论】:

    猜你喜欢
    • 2021-10-29
    • 2020-12-19
    • 2021-09-25
    • 1970-01-01
    • 2018-06-29
    • 1970-01-01
    • 1970-01-01
    • 2023-03-18
    • 1970-01-01
    相关资源
    最近更新 更多