docker build - 避免添加仅在构建时需要的文件

Old*_*ide 6 docker dockerfile docker-build

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

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

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

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

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

Eri*_*kMD 1

依赖docker commit确实相当于黑客:),因此一些参考文献(例如这篇博客文章)提到它的使用是不可取的。

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

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

RUN curl -OL https://example.com/foo.deb && dpkg -i foo.deb && rm -f foo.deb
Run Code Online (Sandbox Code Playgroud)

如果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/*
Run Code Online (Sandbox Code Playgroud)

也许还有另一种可能的解决方案(但我不认为多阶段构建Docker 功能在这里会有一些帮助,因为所有权限都会因执行例如而丢失COPY --from=build / /)。