php - 在构建 Docker 时,如何将 Composer 缓存存储在卷中?

标签 php docker composer-php

我正在使用此 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 的缓存存储在名为 composer-cache 的卷中。但 Composer 不会在该卷中存储任何数据。

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

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

最佳答案

您的问题是指令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...

这将使首次安装后的安装执行速度更快。

要获得下载速度(这可能使上述内容相对毫无意义),您可以使用 Prestssimo 。这是一个 Composer 插件,使 Composer 下载并行而不是顺序执行。

(请注意,对于 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 .

<强> It is not currently possible使用 docker-compose 来启用 buildkit。但是,通过一些预先计划,您可以先构建镜像,然后在 docker-compose 文件中声明这些镜像以进行编排。

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

关于php - 在构建 Docker 时,如何将 Composer 缓存存储在卷中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59017965/

相关文章:

java - 为什么通常不允许嵌套 block 注释?

php - 使用 jquery ajax 上传多个图像并使用 php 处理它们

docker - Quarkus:测试容器内置的原生镜像

node.js - 为什么 docker build 中的 COPY 未检测到更新

ruby-on-rails - Rails 在基于 Rancher 的 Docker 环境和 Postgresql 中运行缓慢

php - Composer 和 Linux 生产服务器 - 自动加载不工作

git - composer.json 指定了依赖,但是没有找到composer.lock

PHP/MySQL - 在数据库中存储数组

phpredis无法连接到127.0.0.1 :6379

php - Laravel 5.1 Package Development - 在开发中加载包依赖