重复清理 apt 缓存的好处

43
在追求越来越小的Docker镜像时,通常会在安装软件包后删除apt(适用于基于Debian/Ubuntu的镜像)缓存。类似这样的操作:
RUN rm -rf /var/lib/apt/lists/*

我见过一些Dockerfile,在每次安装软件包后都会执行此操作(example),即按照以下模式进行:

# Install some package
RUN apt-get update \
    && apt-get install -y <some-package> \
    && rm -rf /var/lib/apt/lists/*

# Do something
...

# Install another package
RUN apt-get update \
    && apt-get install -y <another-package> \
    && rm -rf /var/lib/apt/lists/*

# Do something else
...

这样做有什么好处,而不是在最后只清理一次apt缓存(因此仅在开头更新一次)? 对我来说,似乎需要多次删除和更新缓存只会减慢镜像构建的速度。

1个回答

55

人们这样做的主要原因是为了最小化存储在特定 Docker 层中的数据量。在拉取 Docker 镜像时,您必须拉取该层的整个内容。

例如,想象一下镜像中以下两个层:

RUN apt-get update
RUN rm -rf /var/lib/apt/lists/*
第一个RUN命令会生成一个包含列表的层。这些列表将始终被任何使用你的镜像的人拉取,即使下一个命令移除了这些文件(因此无法访问)。最终,这些额外的文件只是浪费空间和时间。
另一方面,
RUN apt-get update && rm -rf /var/lib/apt/lists/*

在单个层内进行这样的操作,列表在层完成之前被删除,因此它们永远不会作为镜像的一部分推送或拉取。

那么,为什么要使用多个使用apt-get install的层?这很可能是为了使人们在其他镜像中更好地利用层,因为如果它们在顺序上是相同的,则Docker将在镜像之间共享层,以节省服务器空间并加快构建和拉取速度。


7
那是否意味着,在最后一步使用 RUN rm -rf /var/lib/apt/lists/* 命令并不能真正缩小最终的映像,因为之前的层中APT缓存仍然存在? - jmd_dk
5
一个独立的 RUN rm ... 步骤实际上并不会使镜像变小。 - David Maze
2
https://docs.docker.com/develop/develop-images/dockerfile_best-practices/提到:“官方的Debian和Ubuntu镜像会自动运行`apt-get clean,因此不需要显式调用。”这是否与rm -rf /var/lib/apt/lists/*`无关? - Anon
3
不;apt-get clean会删除下载以安装软件包的安装程序文件。rm -rf /var/lib/apt/lists/*会删除用于确定可安装软件包的列表。说实话,删除这些列表几乎不会节省多少空间,但如果您想制作最小的映像,尤其是如果您要发布供其他人使用的映像,这样做似乎是正确的选择。 - Ben XO
4
多次使用 apt-get install 的另一个原因是为了调试构建过程。如果您尝试安装100个软件包,但总是失败,那么您必须重新安装这100个软件包。将构建划分为两个或更多的 RUN 可以将第一组已安装的内容缓存为镜像,同时您可以调试第二个组。一旦全部成功后,您可以选择将它们合并在一起。 - Daniel Griscom
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接