如何在不使用缓存层但使用前一阶段的缓存的情况下构建多阶段 Docker 构建的每个部分

时间:2021-06-08 12:13:33

标签: docker docker-multi-stage-build docker-layer

我有一个 4 阶段的 Dockerfile,如下所示,但是当我不想使用缓存时,我无法找到优化构建的最佳方法(以确保最新的图像和包使用)...

FROM composer:latest as api_platform_composer

FROM php:7.4-fpm-alpine AS api_platform_php
RUN apk upgrade --no-cache
RUN apk add --no-cache {some packages}
RUN set -eux; \
    apk add --no-cache --virtual .build-deps $PHPIZE_DEPS {some packages}; \
    docker-php-ext-configure {some packages}; \
    docker-php-ext-install -j$(nproc) {some packages}; \
    pecl install {some packages}; \
    pecl clear-cache; \
    docker-php-ext-enable {some packages}; \
    runDeps="$( \
        scanelf --needed --nobanner --format '%n#p' --recursive /usr/local/lib/php/extensions \
            | tr ',' '\n' \
            | sort -u \
            | awk 'system("[ -e /usr/local/lib/" $1 " ]") == 0 { next } { print "so:" $1 }' \
    )"; \
    apk add --no-cache --virtual .phpexts-rundeps $runDeps; \
    apk del .build-deps
COPY --from=api_platform_composer /usr/bin/composer /usr/bin/composer
# … various other steps…
# etc.

FROM openresty/openresty:1.17.8.2-alpine AS api_platform_nginx
RUN apk upgrade --no-cache
RUN echo -e "env UPSTREAM;\n$(cat /usr/local/openresty/nginx/conf/nginx.conf)" > /usr/local/openresty/nginx/conf/nginx.conf
COPY src/docker/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf
WORKDIR /srv/api/public
COPY --from=api_platform_php /srv/api/public ./

FROM alpine:3 as api_platform_ssh
# No dependencies from above

目前我使用以下命令分别构建每个 phpnginxssh 容器......

docker build --target api_platform_php \
  --cache-from registry.digitalocean.com/good-technologies/crm:latest-php,registry.digitalocean.com/good-technologies/crm:1.0.0-beta2-php \
  --build-arg BUILDKIT_INLINE_CACHE=1 \
  --build-arg BASE_COMPOSER_IMAGE=gitlab.com/good-technologies/dependency_proxy/containers/composer:latest \
  --build-arg BASE_PHP_IMAGE=gitlab.com/good-technologies/dependency_proxy/containers/php:7.4-fpm-alpine \
  --build-arg BASE_OPENRESTY_IMAGE=gitlab.com/good-technologies/dependency_proxy/containers/openresty/openresty:1.17.8.2-alpine \
  --build-arg BASE_SSH_IMAGE=gitlab.com/good-technologies/dependency_proxy/containers/alpine:3 \
  --build-arg BASE_MONGODB_IMAGE=gitlab.com/good-technologies/dependency_proxy/containers/mongo:4.4 \
  --build-arg BASE_VARNISH_IMAGE=gitlab.com/good-technologies/dependency_proxy/containers/varnish:6.4 \
  --tag registry.digitalocean.com/good-technologies/crm:1.0.0-beta2-php \
  --progress=plain \
  --no-cache \
  --pull \
  --secret id=php-secrets,src=.secrets/php/.secrets \
  .

docker build --target api_platform_nginx \
  --cache-from registry.digitalocean.com/good-technologies/crm:latest-nginx,registry.digitalocean.com/good-technologies/crm:1.0.0-beta2-php,registry.digitalocean.com/good-technologies/crm:1.0.0-beta2-nginx \
  --build-arg BUILDKIT_INLINE_CACHE=1 \
  --build-arg BASE_COMPOSER_IMAGE=gitlab.com/good-technologies/dependency_proxy/containers/composer:latest \
  --build-arg BASE_PHP_IMAGE=gitlab.com/good-technologies/dependency_proxy/containers/php:7.4-fpm-alpine \
  --build-arg BASE_OPENRESTY_IMAGE=gitlab.com/good-technologies/dependency_proxy/containers/openresty/openresty:1.17.8.2-alpine \
  --build-arg BASE_SSH_IMAGE=gitlab.com/good-technologies/dependency_proxy/containers/alpine:3 \
  --build-arg BASE_MONGODB_IMAGE=gitlab.com/good-technologies/dependency_proxy/containers/mongo:4.4 \
  --build-arg BASE_VARNISH_IMAGE=gitlab.com/good-technologies/dependency_proxy/containers/varnish:6.4 \
  --tag registry.digitalocean.com/good-technologies/crm:1.0.0-beta2-nginx \
  --progress=plain \
  --no-cache \
  --pull \
  --secret id=php-secrets,src=.secrets/php/.secrets \
  .

docker build --target api_platform_ssh \
  --cache-from registry.digitalocean.com/good-technologies/crm:latest-ssh,registry.digitalocean.com/good-technologies/crm:1.0.0-beta2-ssh \
  --build-arg BUILDKIT_INLINE_CACHE=1 \
  --build-arg BASE_COMPOSER_IMAGE=gitlab.com/good-technologies/dependency_proxy/containers/composer:latest \
  --build-arg BASE_PHP_IMAGE=gitlab.com/good-technologies/dependency_proxy/containers/php:7.4-fpm-alpine \
  --build-arg BASE_OPENRESTY_IMAGE=gitlab.com/good-technologies/dependency_proxy/containers/openresty/openresty:1.17.8.2-alpine \
  --build-arg BASE_SSH_IMAGE=gitlab.com/good-technologies/dependency_proxy/containers/alpine:3 \
  --build-arg BASE_MONGODB_IMAGE=gitlab.com/good-technologies/dependency_proxy/containers/mongo:4.4 \
  --build-arg BASE_VARNISH_IMAGE=gitlab.com/good-technologies/dependency_proxy/containers/varnish:6.4 \
  --tag registry.digitalocean.com/good-technologies/crm:1.0.0-beta2-ssh \
  --progress=plain \
  --no-cache \
  --pull \
  --secret id=php-secrets,src=.secrets/php/.secrets \
  .

问题在于,因为我使用了 --no-cache 标志,所以每个后续阶段都会重新构建它们所依赖的早期阶段。

有时我可能只想构建容器映像的子集。

我有哪些优化选项?我可以想到以下...

  1. 根据 Dockerfile 中的顺序确定我们想要构建的最后一个镜像,并首先使用 --no-cache 标志构建最后一个,然后构建其余所有镜像,不带 {{ 1}} 标志。

  2. 在我需要确保不使用缓存的每个步骤中使用随机值构建参数,类似这样的......

    --no-cache

    ... 然后为每个构建命令传入相同的时间戳。

我是否在正确的轨道上使用其中之一,或者还有其他更好的选择吗?

0 个答案:

没有答案