【问题标题】:Why docker needs to build all the previous stages?为什么 docker 需要构建之前的所有阶段?
【发布时间】:2021-09-07 15:37:16
【问题描述】:

我需要在一个普通阶段的基础上构建 2 个阶段

$ ls
Dockerfile  dev  other  prod

$ cat Dockerfile
FROM scratch as dev
COPY dev /

FROM scratch as other
COPY other /

FROM scratch as prod
COPY --from=dev /env /
COPY prod /

如您所见,prod 阶段不依赖于other 阶段,但无论如何它都会构建它

$ docker build . --target prod
Sending build context to Docker daemon  4.096kB
Step 1/7 : FROM scratch as dev
 ---> 
Step 2/7 : COPY dev /
 ---> 64c24f1f1d8c
Step 3/7 : FROM scratch as other
 ---> 
Step 4/7 : COPY other /
 ---> 9b0753ec4353
Step 5/7 : FROM scratch as prod
 ---> 
Step 6/7 : COPY --from=dev /dev /
 ---> Using cache
 ---> 64c24f1f1d8c
Step 7/7 : COPY prod /
 ---> 9fe8cc3d3ac1
Successfully built 9fe8cc3d3ac1

为什么 Docker 需要构建 other 层?

如何在没有 other 的情况下构建 prod ?我必须使用另一个 Dockerfile 吗?

【问题讨论】:

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


    【解决方案1】:

    docker build 有两个不同的后端。 “经典”后端的工作方式与您描述的完全一样:它贯穿整个 Dockerfile 直到到达最后阶段,因此即使一个阶段未使用,它仍然会被执行。较新的BuildKit backend 可以进行一些依赖性分析并确定某个阶段从未使用过,并根据您的要求跳过它。

    当前版本的 Docker 使用 BuildKit 作为其默认后端。稍旧的版本有 BuildKit 可用,但它不是默认的。您可以通过运行来启用它

    export DOCKER_BUILDKIT=1
    

    在您运行 docker build 的 shell 环境中。

    (最佳实践通常是在所有环境中运行相同的 Docker 映像,并为不同的组件使用不同的 Dockerfile。这样可以避免关于确切运行哪些阶段的任何问题。)

    【讨论】:

    • BuildKit 看起来很有趣,它正在做我正在搜索的事情。从现在开始我会尝试使用它
    猜你喜欢
    • 1970-01-01
    • 2022-01-08
    • 1970-01-01
    • 1970-01-01
    • 2020-04-26
    • 1970-01-01
    • 2016-09-26
    • 2016-06-02
    • 1970-01-01
    相关资源
    最近更新 更多