我正在使用此 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/