首页 > 解决方案 > 在构建 docker 期间,如何将作曲家缓存存储在卷中?

问题描述

我正在使用这个 Dockerfile 来创建一个包含我的 PHP 应用程序依赖项的图像:

FROM composer:latest AS composer

COPY ./ ./

VOLUME composer-cache:/tmp/

RUN composer install

FROM php:7.1-fpm

WORKDIR /app

RUN apt-get update && \
    apt-get install -y libpq5 libpq-dev libmemcached11 libmemcached-dev libmagickwand-6.q16-6 libmagickwand-dev unzip --no-install-recommends && \
    docker-php-ext-install pdo pdo_pgsql && \
    pecl install imagick && \
    echo extension=imagick.so >> /usr/local/etc/php/conf.d/imagick.ini && \
    apt-get remove -y libpq-dev libmemcached-dev libmagickwand-dev && \
    apt-get autoremove -y && \
    apt-get autoclean -y

RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"

COPY ./ ./

COPY --from=composer /app/vendor ./vendor

为了更快地构建和减少网络活动,我想将作曲家的缓存存储在名为composer-cache. 但是作曲家不会在该卷中存储任何数据。

我检查了一个官方的作曲家 Dockerfile 并注意到它的导出COMPOSER_HOME环境变量指向/tmp目录。我认为从容器外部存储缓存就足够了,但事实并非如此。

在每次构建时,作曲家都会再次下载所有依赖项,并且卷保持为空。

标签: phpdockercomposer-php

解决方案


您的问题是该指令创建了一个要在运行时使用VOLUME的卷安装点。

该卷实际上是在您执行时创建的docker run。在构建时间 ( docker build) 期间,该指令无效

但是您可以使用为此类事情添加的新构建时间增强功能。

您需要在 Dockerfile 中添加以下内容:

# syntax=docker/dockerfile:experimental
FROM composer:latest AS composer

COPY composer.json composer.lock ./

RUN --mount=type=cache,target=/tmp/cache composer install --prefer-dist --no-suggest

### your next build stage...

这将导致install第一次之后的执行速度更快。

要获得下载速度(这可能会使上述内容相对没有实际意义),您可以使用Prestssimo。这是一个作曲家插件,它使作曲家下载并行执行而不是顺序执行。

(注意,在 Composer 2 中 Prestissimo 已过时,因为 composer 本身执行这种类型的下载优化)。

你最终会得到

# syntax=docker/dockerfile:experimental
FROM composer:latest AS composer
RUN composer global require hirak/prestissimo

COPY composer.json composer.lock ./

RUN --mount=type=cache,target=/tmp/cache composer install --prefer-dist  --no-suggest

### your next build stage...

然后,您将像这样调用您的构建过程:

DOCKER_BUILDKIT=1 docker build .

目前无法使用 docker-compose 来启用 buildkit。但是通过一些预先计划,您可以先构建图像,然后在 docker-compose 文件中声明这些图像以进行编排。

我发现只需使用 Prestissimo 就足够了,不需要额外的缓存层,但您需要检查最适合您的场景的方法。


推荐阅读