如何缓存 docker 构建的包管理器下载?

问题描述 投票:0回答:5

如果我从主机运行

composer install
,我会访问本地作曲家缓存:

  - Installing deft/iso3166-utility (1.0.0)
    Loading from cache

然而,在构建 Dockerfile 中包含以下内容的容器时:

RUN composer install -n -o --no-dev

我下载了所有东西,例如:

  - Installing deft/iso3166-utility (1.0.0)
    Downloading: 100%         

这是预料之中的,但我想避免它。即使在重建时,它也会再次下载所有内容。

我希望有一个用于 Composer 的通用缓存,我也可以为其他 Docker 项目重新共享它。

我对此进行了研究,找到了在 Dockerfile 中定义卷的方法

ENV COMPOSER_HOME=/var/composer
VOLUME /var/composer

我将其添加到我的

Dockerfile
中,并预计只下载一次文件,然后再访问缓存。

然而,当我修改我的

composer
时,例如删除
-o
标志,然后重新运行
docker build .
,我预计会在构建时命中缓存,但我仍然再次下载供应商。

卷应该如何工作才能在 Docker 容器内拥有数据缓存?

caching docker composer-php docker-volume diskcache
5个回答
9
投票

使用实验性功能:Docker buildkit(自 docker 18.09、docker-compose 1.25.4 起支持)

在你的 dockerfile 中

# syntax=docker/dockerfile:experimental
FROM ....
# ......  
RUN --mount=type=cache,target=/var/composer composer install -n -o --no-dev

现在在构建之前,请确保导出环境变量:

export DOCKER_BUILDKIT=1
docker build ....

如果您使用 docker-compose,请确保也导出

COMPOSE_DOCKER_CLI_BUILD
:

export COMPOSE_DOCKER_CLI_BUILD=1 DOCKER_BUILDKIT=1
docker-compose build ...

如果它不能与 docker-compose 一起使用,请确保您的 docker-compose 版本高于 1.25.4

docker-compose version

4
投票

我找到了两种处理这个问题的方法,但没有一种方法可以再处理作曲家卷。

  1. 紧固composer下载过程:使用hirak/prestissimo

    composer global require "hirak/prestissimo:^0.3"
    

💡 使用 Composer 2.0,不再需要以加快下载速度。事实上,它不会安装在 Composer 2.0 环境中。

  1. 强制 docker 使用缓存的 Composer 安装。
    如果添加的文件没有更改,Docker 将在

    RUN
    上使用缓存。如果您只执行
    COPY . /your-php-app
    docker build
    将刷新所有现金并重新运行composer install,即使源代码树中只有一个不相关的文件发生了更改。
    为了使 docker build 运行composer install 仅在软件包更改时安装,必须在添加源文件之前添加
    composer.json
    composer.lock
    文件。由于无论如何也需要源文件,因此必须使用不同的文件夹来安装 Composer 并将内容同步回然后添加的文件夹;此外,还必须手动运行安装后脚本。
    它应该看起来像这样(未经测试):

    WORKDIR /tmp/
    COPY composer.json composer.lock ./
    RUN composer install -n -o --no-dev --no-scripts
    
    WORKDIR /your-php-app/ 
    COPY . /your-php-app/
    RUN rsync -ah /tmp/* /your/php-app/
    RUN composer run-script post-install-cmd
    

或将两者结合=)


2
投票

我希望有一个用于 Composer 的通用缓存,我也可以为其他 Docker 项目重新共享它。

在使用容器时,为 Composer 缓存使用共享卷非常有效。如果您想要的范围不仅仅是容器,并使用共享缓存,例如本地开发也是如此,我开发了一个名为 Velocita 的解决方案 - 它是如何工作的

基本上,您可以为本地项目以及内部和构建容器使用一个全局 Composer 插件。这不仅极大地加快了下载速度,还有助于解决第 3 方中断等问题。


0
投票

我会考虑使用

$HOME/.composer/cache/files
目录。这是使用 Composer 安装时 Composer 读取/写入的位置。

如果您能够将其从主机安装到容器,那就可以了。您也可以在每次跑步

composer install
后将其涂上焦油,然后在下次跑步
composer install
之前将其放入。

这就是 Travis CI 建议的做法。

此外,请考虑将

--prefer-dist
标志与
composer install
命令一起使用。

有关信息可以在这里找到:https://getcomposer.org/doc/03-cli.md#install

--prefer-dist:与--prefer-source相反,如果可能的话,composer将从dist安装。这可以大大加快构建服务器和其他通常不运行供应商更新的用例上的安装速度。如果您没有正确的设置,这也是规避 git 问题的一种方法。

有关使用作曲家缓存的一些参考:


0
投票

从现在开始寻找这个的任何人都应该能够使用

RUN --mount=type=cache,target=/root/.composer/ composer install

这个一般原则似乎适用于大多数软件包安装程序,你只需要找到正确的缓存目录(

npm
使用
$HOME/.npm
等),如果你不构建为
root
,它显然会改变。

© www.soinside.com 2019 - 2024. All rights reserved.