【问题标题】:docker build - Avoid ADDing files only needed at build timedocker build - 避免只在构建时添加文件
【发布时间】:2019-02-12 04:17:52
【问题描述】:

我正在尝试构建一个 docker 映像来避免不必要的体积,我遇到了一个我认为应该很常见的问题,但到目前为止我还没有找到一个简单的解决方案。 (我在 ubuntu 18.04 系统上构建 docker,并从 FROM ubuntu 层开始。)

特别是,我需要在映像中安装一个非常大的 .deb 文件(超过 3G)。 COPYADD 然后 RUN dpkg -i 很容易,但这会导致我不需要的几个 GB 空间的重复。当然,仅删除文件并不会减小图像大小。

我希望能够挂载一个卷来访问.deb 文件,而不是COPY 它,这在运行容器时很容易做到,但在构建容器时显然不可能做到?

到目前为止,我想出的是将 docker 构建到我将 ADD 文件的位置,然后在安装卷的情况下运行它,这样我就可以在没有 COPYing 的情况下从容器中访问它它,然后我 dpkg -i 它,然后我执行 docker commit 以从该容器创建图像。果然,我最终得到了一个比我第一次尝试的图像小 3GB 以上的图像,但这似乎是一种 hack,并且使构建脚本变得更加复杂。

我认为必须有更合适的方法来实现这一点,但到目前为止我的搜索还没有找到明显的答案。我错过了什么吗?

【问题讨论】:

    标签: docker dockerfile docker-build


    【解决方案1】:

    依赖docker commit 确实相当于一种黑客攻击:),因此某些参考文献(例如this blog article)提到它的使用是不可取的。

    对于您提到的那种用例,我只看到一种可能的方法(复制一次性 .deb 包,安装它并立即从映像层删除二进制文件):

    您可以使构建映像的 docker 引擎远程可用,您想要安装的 .deb,并将 COPY + RUN 指令替换为单个指令,例如,依赖于 @987654331 @:

    RUN curl -OL https://example.com/foo.deb && dpkg -i foo.deb && rm -f foo.deb
    

    如果 curl 尚未安装,您可以预先运行常用的 APT 命令:

    RUN apt-get update -y -q \
      && DEBIAN_FRONTEND=noninteractive apt-get install -y -q --no-install-recommends \
        ca-certificates \
        curl \
      && apt-get clean \
      && rm -rf /var/lib/apt/lists/*
    

    也许还有另一种可能的解决方案(但我不认为multi-staged builds Docker 功能在这里会有所帮助,因为这样做会丢失所有权限,例如COPY --from=build / /)。

    【讨论】:

    • 谢谢。这很有帮助,但我还是有点傻眼。我认为这是人们经常遇到的事情,并且考虑到在run 期间挂载卷是多么容易,在build 期间执行相同操作似乎是一个明显的功能。你知道为什么他们不只是为构建启用-v 选项吗?
    • @OldGeeksGuid 确实用 Docker 确实不可能做到这一点,因为它会阻碍构建的可移植性/可重复性:这在 stackoverflow.com/questions/26050899/…github.com/moby/moby/issues/3156 中有明显的解释
    • 但是,正如我在回答中提到的那样,存在一些解决方法可以减少对图像大小的影响,而不依赖于 -v + docker commit(另请参见 vsupalov.com/…),但是 TTBOMK只有“您的依赖项的远程可用性+使用单个RUN”才能为您的用例完成这项工作......
    • 我真的不明白再现性论点。与复制或添加相比,它如何影响再现性?我只想要同样的东西,但相当于一个软链接,而不是实际复制一个临时文件然后删除它,在 docker 映像中留下 GB 的未使用和不可用的碎片。相反,我最终运行了一个 http.server 并通过一个临时可用的 URL 连接到本地主机。就我而言,“直截了当”的方式给我留下了 12GB 的 docker 映像。我不妨改用虚拟机。
    • 但似乎可以通过类似“LINK”命令的方式轻松解决它们,即您仍然在构建上下文中拥有这些文件,只是实际上并没有复制它们。
    猜你喜欢
    • 2020-06-06
    • 2017-09-05
    • 2021-05-27
    • 2020-07-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-26
    相关资源
    最近更新 更多