Adding Composer to PHP docker images using multi-stage builds

Multi-stage builds were introduced in docker 17.05 and it can be used to solve the Composer with PHP docker image problem.

It’s a common practice (especially for CI/CD usage) to create a PHP docker image which includes Composer. You can use the official Composer image which is based on the php:7-alpine image. Or you can pick one of the official PHP images and install Composer yourself.

So what’s the problem? You want to install Composer in a secure fashion by checking the hash of the installer (which changes for every version) as documented here. Luckily this has already been done for you in the Composer image’s Dockerfile. So, because Composer is just a single PHAR file, why not copy it into your own image?

This Dockerfile does just that: copy the verified Composer PHAR.

# start with the official Composer image and name it
FROM
composer:1.9.3 AS composer

# continue with the official PHP image
FROM
php:7.4.2

# copy the Composer PHAR from the Composer image into the PHP image
COPY --
from=composer /usr/bin/composer /usr/bin/composer

# show that both Composer and PHP run as expected
RUN
composer --version && php -v

You will notice the FROM instruction allows you to name an image with the AS keyword. You can reference this name in the COPY instruction using the --from= flag.

You can simplify the above into:

# use the official PHP image as base image
FROM
php:7.4.2
# copy the Composer PHAR from the Composer image into the PHP image
COPY --
from=composer:1.9.3 /usr/bin/composer /usr/bin/composer
# show that both Composer and PHP run as expected
RUN
composer --version && php -v

This demonstrates the power of multi-stage builds. It allows you to reuse components from other images and while doing so reduce the complexity (and size) of your own images.

P.S. If you want to run Composer as root you should add this to the Dockerfile:

ENV COMPOSER_ALLOW_SUPERUSER 1