我正在使用这个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