Docker多阶段构建与将工件保留在git中

时间:2019-09-05 19:01:41

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

我的目标容器是构建环境容器,因此我的团队将在统一环境中构建应用。
此应用不一定要作为容器运行-它可以在物理机上运行。该容器仅用于建造。

该应用依赖第三方。
我可以使用apt-get install Dockerfile命令RUN
还有一些我必须自己建造,因为它们需要特殊的建造。

我想知道哪种方法更好。

  1. 使用multistage build似乎很酷; Dockerfile例如:
From ubuntu:18.04 as third_party
RUN apt-get update && apt-get install -y --no-install-recommends \
        build-essential \
        ...
ADD http://.../boost.tar.gz /
RUN tar boost.tar.gz && \
        ... && \
        make --prefix /boost_out ...

From ubuntu:18.04 as final
COPY --from=third_party /boost_out/ /usr/
RUN apt-get update && apt-get install -y --no-install-recommends \
        build-essential \
        ...
CMD ["bash"]
...

优点:

  • 构建最终容器时自动构建
  • 易于更改第三方版本(在此示例中为增强版)

缺点

  • ADD命令每次下载约100MB文件,使映像构建过程变慢
  • 我想使用--cache-from,以便能够缓存third_party并从其他docker主机构建。这意味着我需要在Docker注册表中存储约1.6GB的映像。拉/推非常重。

另一方面

  1. 我可以(使用此third_party图像)构建boost并将其工件存储在某些存储设备中,例如git。大约需要200MB的空间,比存储1.6GB的图像要好。

优点:

  • 较小的磁盘空间

缺点:

  • 笨拙的构建
    • 更改增强版本时,手动构建工件并将其推送到git。
    • 以某种方式将Docker build和git链接起来,以获取最新的工件和COPY到最终映像。

在两种方式下,我都需要一个third_party图像,该图像可以统一并自动构建第三方。在1.中,比2.大的图像将仅包含构建工具,而不包含构建工件。

这是权衡吗?
1.更为自动化,但会占用更多磁盘空间和推/拉时间,
2.繁琐,但占用更少的磁盘空间和推/拉时间?

这些方式是否还有其他优点?

1 个答案:

答案 0 :(得分:1)

我想建议将您的首次尝试更改为以下内容:

FROM ubuntu:18.04 as third_party
RUN apt-get update && apt-get install -y --no-install-recommends \
        build-essential \
        ...
RUN wget http://.../boost.tar.gz -O /boost.tar.gz && \
    tar xvf boost.tar.gz && \
        ... && \
        make --prefix /boost_out ... && \
        find -name \*.o -delete && \
        rm /boost.tar.gz  # this is important!

From ubuntu:18.04 as final
COPY --from=third_party /boost_out/ /usr/
RUN apt-get update && apt-get install -y --no-install-recommends \
        build-essential \
        ...
CMD ["bash"]

这样,您只需要为boost的下载支付一次(在构建不具有缓存的映像时),而不必为原始的tar来源的存储/拉动时间付费。此外,您应该在生成目标文件的同一步骤中从构建文件中删除不需要的目标文件(.o?)。否则,它们也会被存储和拉出。

如果您愿意自由地发布整个Dockerfile,我将很高兴对此进行更深入的研究,并为您提供一些提示。