为多阶段构建自动删除悬空图像并同时支持缓存

Automatic removing of danging images and supporting cache at same time for multi-stage builds

我正在尝试设置一个 CI 构建,它从 Docker 包含多步配置的文件构建图像。

要求如下:

  1. 需要使用 Docker 层缓存,因为它会在 RUN 指令期间加载大量应用依赖项。
  2. 它应该会在每次构建后自动删除旧的悬挂图像。 (为了防止以后手动清理它docker image prune

我的示例解决方案:

(只是为了演示这个问题)看起来像这样:

docker build -t sample-app.
docker rmi $(docker images --filter "dangling=true" -q --no-trunc)

Docker文件:

FROM ubuntu:18.04 AS builder
WORKDIR /app
COPY some-file-for-build.txt /app
RUN echo 'building...'

FROM ubuntu:18.04
CMD ["echo", "running..."]

问题:

由于删除了悬空图像,缓存变得无效并且 RUN 指令在每次构建期间执行。

单阶段配置的意外行为

但如果删除第 2 步,则将 Docker 文件更改为:

FROM ubuntu:18.04
WORKDIR /app
COPY some-file-for-build.txt /app
RUN echo 'building...'

缓存开始为 RUN 指令工作。

Step 4/4 : RUN echo 'building...'
 ---> Using cache
 ---> 9c7c15230600

问题:

  • 您需要使用Docker 18.09 及以上版本,还需要设置环境变量DOCKER_BUILDKIT=1。此环境变量允许使用 BuildKit 功能,这反过来又允许更高性能 docker 构建和缓存可能性以减少构建时间。您可以获得更多信息here

  • 据我所知,使用 Docker >18.09.

  • 缓存可用于单级和多级配置

Docker文件:

FROM ubuntu:18.04 AS builder
WORKDIR /app
COPY some-file-for-build.txt /app
RUN echo 'building...'

FROM ubuntu:18.04
WORKDIR /app
COPY --from=builder /app/some-file-for-build.txt some-file-for-build-from-builder-stage.txt
CMD ["bash"]

这是我的 docker 构建和清理的日志:

> docker build --pull --rm -f "61977760.Dockerfile" -t 61977760:latest "."
[+] Building 4.7s (10/10) FINISHED                                                                                                                                       
 => [internal] load .dockerignore                                                                                                                                   0.0s
 => => transferring context: 2B                                                                                                                                     0.0s
 => [internal] load build definition from 61977760.Dockerfile                                                                                                       0.1s
 => => transferring dockerfile: 289B                                                                                                                                0.0s
 => [internal] load metadata for docker.io/library/ubuntu:18.04                                                                                                     2.4s
 => [internal] load build context                                                                                                                                   0.0s
 => => transferring context: 44B                                                                                                                                    0.0s
 => [builder 1/4] FROM docker.io/library/ubuntu:18.04@sha256:3235326357dfb65f1781dbc4df3b834546d8bf914e82cce58e6e6b676e23ce8f                                       0.3s
 => => resolve docker.io/library/ubuntu:18.04@sha256:3235326357dfb65f1781dbc4df3b834546d8bf914e82cce58e6e6b676e23ce8f                                               0.0s
 => => sha256:3235326357dfb65f1781dbc4df3b834546d8bf914e82cce58e6e6b676e23ce8f 1.42kB / 1.42kB                                                                      0.0s
 => => sha256:b58746c8a89938b8c9f5b77de3b8cf1fe78210c696ab03a1442e235eea65d84f 1.15kB / 1.15kB                                                                      0.0s
 => => sha256:c3c304cb4f22ceb8a6fcc29a0cd6d3e4383ba9eb9b5fb552f87de7c0ba99edac 3.41kB / 3.41kB                                                                      0.0s
 => [builder 2/4] WORKDIR /app                                                                                                                                      0.0s
 => [builder 3/4] COPY some-file-for-build.txt /app                                                                                                                 0.0s
 => [builder 4/4] RUN echo 'building...'                                                                                                                            0.8s
 => [stage-1 3/3] COPY --from=builder /app/some-file-for-build.txt some-file-for-build-from-builder-stage.txt                                                       0.0s
 => exporting to image                                                                                                                                              0.9s
 => => exporting layers                                                                                                                                             0.8s
 => => writing image sha256:94fd1e56c8044f0e2f80ee83c784cca5f2c384fd4eba9210f9ff81db68f406e5                                                                        0.0s
 => => naming to docker.io/library/61977760:latest                                                                                                                  0.0s
> docker rmi $(docker images --filter "dangling=true" -q --no-trunc)      
Deleted: sha256:4d157078805ccf08fd42502b19a665a0b60e80a33a7c5b6485e6fd201ca91cc1
Deleted: sha256:6f7f45cca948cf855afea76ff73878b8348da6ed2652d62b48f992f7d9768822
Deleted: sha256:eefe65e58b69e4567c5145828ec95d1d9f3477709cc76fb571e204920df8e378
> docker build --pull --rm -f "61977760.Dockerfile" -t 61977760:latest "."
[+] Building 0.9s (10/10) FINISHED                                                                                                                                       
 => [internal] load .dockerignore                                                                                                                                   0.0s
 => => transferring context: 2B                                                                                                                                     0.0s
 => [internal] load build definition from 61977760.Dockerfile                                                                                                       0.1s
 => => transferring dockerfile: 47B                                                                                                                                 0.0s
 => [internal] load metadata for docker.io/library/ubuntu:18.04                                                                                                     0.8s
 => [builder 1/4] FROM docker.io/library/ubuntu:18.04@sha256:3235326357dfb65f1781dbc4df3b834546d8bf914e82cce58e6e6b676e23ce8f                                       0.0s
 => [internal] load build context                                                                                                                                   0.0s
 => => transferring context: 42B                                                                                                                                    0.0s
 => CACHED [builder 2/4] WORKDIR /app                                                                                                                               0.0s
 => CACHED [builder 3/4] COPY some-file-for-build.txt /app                                                                                                          0.0s
 => CACHED [builder 4/4] RUN echo 'building...'                                                                                                                     0.0s
 => CACHED [stage-1 3/3] COPY --from=builder /app/some-file-for-build.txt some-file-for-build-from-builder-stage.txt                                                0.0s
 => exporting to image                                                                                                                                              0.0s
 => => exporting layers                                                                                                                                             0.0s
 => => writing image sha256:94fd1e56c8044f0e2f80ee83c784cca5f2c384fd4eba9210f9ff81db68f406e5                                                                        0.0s
 => => naming to docker.io/library/61977760:latest                                                                                                                  0.0s
> docker builder prune --all                                              
WARNING! This will remove all build cache. Are you sure you want to continue? [y/N] y
Deleted build cache objects:
np9zknowpkgi9aa2qtfstthnr
l0lucvc40nl98ceqxqadjplaw
elj14uwncgbk928oawwalht9x
s4l0w4h3day53tc3w20njd9cm
t6br3zadzcqhwilswvhkc2qkv
q8wrflxp3sppgmrft0yv805l0
qbe59a3kgjdvaw4ng7d5rasc8
sha256:82751c4dcc36265daceeee0abd938806b591eb66700863186377348c96e8aead
sha256:24b16cac34768092d57cdb429a12de6c9ee870a3724d70098a189ae0ac344c42
sha256:b1daff3b271fede2bec31812c398e28952f792935f608e467271cdfaccab7de2
sha256:b7f7d2967507ba709dbd1dd0426a5b0cdbe1ff936c131f8958c8d0f910eea19e

Total reclaimed space: 64.21MB
>