Caching 如何缓存docker版本的package manager下载?

Caching 如何缓存docker版本的package manager下载?,caching,docker,composer-php,docker-volume,diskcache,Caching,Docker,Composer Php,Docker Volume,Diskcache,如果我从主机运行composer安装,我会访问本地composer缓存: - 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安装
,我会访问本地composer缓存:

  - 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%         
这是意料之中的,但我喜欢避免。即使是在重建后的服务器上,它也会再次下载所有内容

我想有一个通用缓存的作曲家,我也可以重新为其他docker项目共享

我对此进行了调查,并找到了以下方法:

我将其添加到我的
Dockerfile
,并希望只下载一次文件,然后点击缓存

然而,当我修改我的
composer
时,例如删除
-o
标志,然后重新运行
docker build.
,我希望在构建时命中缓存,但我仍然再次下载供应商


卷应该如何工作才能在docker容器中具有数据缓存?

我找到了两种处理此问题的方法,但没有一种方法再处理composer卷

  • 紧固composer下载过程:使用

  • 强制docker使用缓存的composer安装
    如果添加的文件没有更改,Docker将在
    运行时使用缓存。如果你只做
    复制/您的php应用程序
    docker build
    将刷新所有现金并重新运行composer安装,即使源代码树中只有一个不相关的文件发生了更改
    为了使docker build仅在包更改时运行composer install,必须在添加源文件之前添加
    composer.json
    composer.lock
    文件。由于用户还需要源文件,因此必须使用不同的文件夹进行composer安装,并将内容重新同步到随后添加的文件夹中;此外,还必须手动运行安装后脚本。
    它应该是这样的(未测试):


  • 我将考虑使用<代码> $HOM//Cyror /Cache /文件< /COD>目录。这是使用composer安装时composer读取/写入的位置

    如果您能够将它从主机装载到您的容器中,那么它就可以工作了。此外,您可以在每次运行
    composer安装
    后对其加上焦油,然后在下次运行
    composer安装
    之前将其放入

    这就是Travis CI建议这样做的大致方式

    也可以考虑使用<代码> -喜欢DIST<代码>标记与你的代码>作曲家安装< /代码>命令。

    可在此处找到有关的信息:

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

    有关为您使用composer缓存的一些参考资料:


    使用实验性功能: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\u docker\u CLI\u BUILD

    export COMPOSE_DOCKER_CLI_BUILD=1 DOCKER_BUILDKIT=1
    docker-compose build ...
    
    如果docker compose无法使用,请确保docker compose版本高于1.25.4

    docker-compose version
    

    该卷将在容器实例中保持,但不会在生成时保持。您可以创建一个命名卷,该卷将保持在静态位置,但随后将解决方案耦合到环境。您需要考虑在构建和之后要做什么。您可以设置某种本地存储库作为缓存/代理。我也在努力解决这个问题。你找到办法了吗?我想也许使用HTTP代理并指导Docker使用它可以奏效。可能会将hub.docker.com从代理中排除,以不保留下载图像的两份副本。@古力就我如何处理该问题给出了答案。谢谢提醒。这个答案很奇怪。。。它似乎绕过了从您的应用程序中绑定挂载的问题。现在发生的事情(据我猜测)是您的
    供应商/
    目录被完全复制,因此composer不需要重新下载(或安装)任何内容。这可能会产生跨平台的后果。@Christian您在考虑什么样的跨平台问题?我将此Dockerfile用于开发和生产。根据经验,如果您使用某个使用特定于平台的可执行文件的composer软件包,composer不够聪明,无法意识到应该重新安装该软件包。无论如何,为了回答您上面的(暗示的)问题,docker compose(可能还有docker?)不知何故,在构建期间不会装载卷绑定。我知道一个可行的选择是使用GitLab CI,而不是使用普通的docker-compose构建。如果能够使用docker 17.05或更高版本,我宁愿使用一个。docker引擎的最小版本是什么?18.09。。我将把它添加到应答器中,而不是导出var,还可以将它包含在命令本身中:
    DOCKER\u BUILDKIT=1 DOCKER build。
    @k0pernikus Composer cache位于
    export DOCKER_BUILDKIT=1
    docker build ....
    
    export COMPOSE_DOCKER_CLI_BUILD=1 DOCKER_BUILDKIT=1
    docker-compose build ...
    
    docker-compose version