How to cache package manager downloads for docker builds? How to cache package manager downloads for docker builds? docker docker

How to cache package manager downloads for docker builds?


Use the experimental feature : Docker buildkit (Supported Since docker 18.09, docker-compose 1.25.4)

In your dockerfile

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

Now before building, make sure the env var is exported:

export DOCKER_BUILDKIT=1docker build ....

If you are using docker-compose, make sure to export also COMPOSE_DOCKER_CLI_BUILD :

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

If it does not work with docker-compose, make sure your docker-compose version is above 1.25.4

docker-compose version


I found two ways of dealing with this problem, yet none deal with composer volumes anymore.

  1. Fasten composer download process: Use hirak/prestissimo

    composer global require "hirak/prestissimo:^0.3"

💡 With Composer 2.0, the above step is no longer required for faster downloads. In fact, it won't install on Composer 2.0 environments.

  1. Force docker to use a cached composer install.
    Docker uses a cache on a RUN if the added files didn't change. If you only do COPY . /your-php-app, docker build will refresh all the cashes and re-run composer install even if only one unrelated file in the source tree changed.
    In order to make docker build to run composer install only install on package changes, one has to add composer.json and composer.lock file before adding the source files. Since one also needs the source files anyway, one has to use different folders for composer install and rsync the content back to the then added folder; furthermore one then has to run the post-install scripts manually.
    It should look something like this (untested):

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

or combine the two =)


I would consider utilizing the $HOME/.composer/cache/files directory. This is where composer reads/write to when using composer install.

If you are able to mount it from your host to your container that would work. Also you could just tar it up after each time your run composer install and then drop that in before you run composer install the next time.

This is loosely how Travis CI recommends doing this.

Also, consider using the --prefer-dist flag with your composer install command.

Info on that can be found here: https://getcomposer.org/doc/03-cli.md#install

--prefer-dist: Reverse of --prefer-source, composer will install from dist if possible. This can speed up installs substantially on build servers and other use cases where you typically do not run updates of the vendors. It is also a way to circumvent problems with git if you do not have a proper setup.

Some references on utilizing the composer cache for you: