首页 > 解决方案 > Docker:我应该将我的 apt-get install / build / cleanup 步骤合并到一个大的 RUN 中吗?

问题描述

我有一个看起来像这样的 Dockerfile:

FROM debian:stable-slim

RUN apt-get update && \
    apt-get install -y --no-install-recommends fp-compiler fp-units-fcl fp-units-net libc6-dev

COPY src /whatwg/wattsi/src

WORKDIR /whatwg/wattsi/src
RUN ./build.sh

RUN rm -rf /whatwg/wattsi/src && \
    apt-get purge -y fp-compiler fp-units-fcl fp-units-net libc6-dev && \
    apt-get autoremove -y

ENTRYPOINT ["/whatwg/wattsi/bin/wattsi"]

如您所见,有三个单独的 RUN 步骤:一个是安装依赖项,一个是构建,一个是构建后清理。

我一直在四处寻找,试图弄清楚为什么生成的图像相对较大,这似乎是因为,即使我做了一个清理步骤,仍然保留了一个包含所有已安装依赖项的层。

我应该像这样重组我的 Dockerfile 吗?

FROM debian:stable-slim

COPY src /whatwg/wattsi/src
WORKDIR /whatwg/wattsi/src

RUN apt-get update && \
    apt-get install -y --no-install-recommends fp-compiler fp-units-fcl fp-units-net libc6-dev && \
    ./build.sh && \
    rm -rf /whatwg/wattsi/src && \
    apt-get purge -y fp-compiler fp-units-fcl fp-units-net libc6-dev && \
    apt-get autoremove -y

ENTRYPOINT ["/whatwg/wattsi/bin/wattsi"]

这感觉有点“被压扁”,我找不到任何明确推荐它的文档。所有说“最小化RUN命令”的文档似乎都集中在不执行多个apt-get步骤上;它并没有谈论将所有内容压缩为一体。但也许这是正确的做法?

标签: dockerdockerfile

解决方案


Docker 映像中的每一层就像版本控制中的提交,不能更改之前的层,就像在 Git 中删除文件不会将其从历史记录中删除一样。因此,从前一层删除文件不会使图像变小。

由于图层是在 RUN 结束时创建的,所以做你正在做的事情确实是制作更小的图像的一种方法。正如有人提到的,另一个是多阶段构建。

单一 RUN 变体的缺点是每次源代码更改时都必须重新运行整个程序。所以你每次都需要 apt-get 所有这些包,而不是依赖 Docker 的构建缓存(我在这里写了一篇解释缓存的东西:https ://pythonspeed.com/articles/docker-caching-model/ )。

因此,多阶段可以让您通过缓存更快地构建和小图像。但是做对是很复杂的,你所做的更简单更容易。


推荐阅读