Speedy Composer installs in Docker builds
I’m going to share a few optimisations you can make to speed up
composer installs in Docker builds.
- Turn off Xdebug
- Composer install before codebase
0. Optimisation zero
There’s also an optimisation zero. I refrained from adding it to the list above because you should just be doing this anyway. Basically, commit your
composer.lock. It’s important because it locks the current state (e.g. precise versions) of your dependencies. Other developers or environments should have exactly the same set of dependencies when the lock file is committed.
From a speed perspective,
composer installs will be faster because Composer doesn’t have to calculate which version of dependencies it should install.
Prestissimo is a spiffing plugin for Composer which parallelises all the downloads. You just have to install it to see sometimes large speed increases — no configuration is needed. Installing it locally is simple as:
composer global require hirak/prestissimo
To leverage it in a Docker build, install Composer in your
Dockerfile with the following:
RUN curl -sS https://getcomposer.org/installer | php && mv composer.phar /usr/local/bin/composer && composer global require hirak/prestissimo --no-plugins --no-scripts
2. Turn off Xdebug
Composer runs much quicker with Xdebug disabled. Many Linux distributions have a CLI command called
phpdismod. You can use it to disable Xdebug in your
RUN phpdismod xdebug
If you’re installing PHP yourself as part of your image, you could also just not install Xdebug at all. It’s probably best to keep it out of production images anyway.
3. Composer install before codebase
Docker caches ‘layers’ within your images. When a layer changes, it invalidates the cache for all layers after it. This means a well optimised
Dockerfile has things that don’t change much in base layers and stuff that changes frequently in later layers.
If you make the assumption that you change your codebase more often than your Composer dependencies — then your
Dockerfile should run
composer install before copying across your codebase. This will mean that your
composer install layer will be cached even if your codebase changes. The layer will only be invalidated when you actually change your dependencies (
# Install dependencies
COPY composer.json composer.json
COPY composer.lock composer.lock
RUN composer install --prefer-dist --no-scripts --no-dev --no-autoloader && rm -rf /root/.composer
# Copy codebase
COPY . ./
# Finish composer
RUN composer dump-autoload --no-scripts --no-dev --optimize
rm -rf /root/.composer line is to remove Composer’s cache. This reduces the size of the resulting image. The location of the
.composer directory may differ on the various Linux distributions.
Important: If you’ve already run Composer in your build context, your local vendor directory would overwrite the one in your build. The most convenient solution for this is to add
/vendor/ to your