2

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

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

我想知道哪种方式更好。

  1. 使用多阶段构建看起来很酷;以 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. 例如,我可以构建 boost(使用此third_party图像)并将其工件存储在一些存储git中。它需要大约 200MB,这比存储 1.6GB 图像要好。

优点:

  • 更小的磁盘空间

缺点:

  • 繁琐的构建
    • 在更改 boost 版本时手动构建和推送工件到 git。
    • 以某种方式链接 Docker build 和 git 以提取最新的工件并COPY连接到最终图像。

在这两种方式中,我都需要一个third_party统一自动构建第三方的图像。在1.比这更大的图像2.中,将只包含构建工具,而不是构建工件。

这是权衡吗?
1.更自动化但消耗更多磁盘空间和推/拉时间,
2.是否繁琐但消耗更少磁盘空间和推/拉时间?

这些方式中的任何一种还有其他美德吗?

4

1 回答 1

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-ed 源的存储/拉取时间付费。此外,您应该在生成它们的同一步骤.o中从构建中删除不需要的目标文件 ( ?)。否则,它们也会被存储和拉取。

如果您可以随意发布整个Dockerfile,我很乐意深入研究它并给您一些提示。

于 2019-09-05T19:10:48.443 回答