在构建 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目录。我认为将缓存存储在容器之外就足够了,但事实并非如此。

在每个构建编辑器上,编辑器都会再次下载所有依赖项,并且卷保持为空。

您的问题是指令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。这是一个作曲家插件,使作曲家下载并行执行而不是顺序执行。

(注意,在作曲家 2 中,Prestissimo 已经过时了,因为作曲家本身会执行这种类型的下载优化(。

你最终会得到

# 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-compos文件中声明这些映像以进行编排。

我发现简单地使用 Prestissimo 就足够了,因为不需要额外的缓存层,但您需要检查最适合您的场景的内容。

您可以通过稍微重组来使用 Dockers 缓存而不是作曲家缓存。

想象一下这个 Dockerfile

FROM php:8.1-cli
COPY --from=composer:2 /usr/bin/composer /usr/bin/composer
WORKDIR /app
COPY . /app
RUN composer install --optimize-autoloader --no-dev

通过在复制应用程序文件之前安装依赖项,可以将依赖项放在单独的缓存层中,该层仅在依赖项更改时更改。你可以这样做:

FROM php:8.1-cli
COPY --from=composer:2 /usr/bin/composer /usr/bin/composer
WORKDIR /app
COPY composer.json composer.lock .
RUN composer install --no-dev
COPY . /app
RUN composer dumpautoload

最新更新