In many of the projects I have seen I have noticed a worrying difference between the production and development environments. It is crucial to minimise the difference between these environments to avoid unexpected bugs.
For the past few years most companies have been using Docker containers in production. Most of the time I noticed that developers were using their own Docker images and that a gap could easily be created between the production and development images. I will detail in this article how I use the docker multi-stage build to reduce this gap β
One Dockerfile to rule them all
This is the pattern I have often seen :
– 1 Dockerfile for developers
– 1 Dockerfile for production
This pattern is bad because it can create a gap between system packages or libraries and cause problems π€―
Instead of last pattern, I recommend using only one Dockerfile with 3 stages :
This second pattern corrects the gap problem if you install your dependencies in the “base” stage.
Concrete example
Let’s say we need PHP 8 + Apache, some php extensions and our developers needs XDebug. Our Dockerfile will look like this :
FROM php:8-apache AS base
RUN docker-php-ext-install \
pdo_mysql \
mysqli
RUN docker-php-ext-enable \
pdo_mysql \
mysqli
FROM base AS dev
RUN mv "$PHP_INI_DIR/php.ini-development" "$PHP_INI_DIR/php.ini"
RUN pecl install xdebug \
&& docker-php-ext-enable xdebug
FROM base AS prod
RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"
To build for development environment you just have to run docker build --target dev .
and see build from stages base + dev :
For production, run docker build --target prod .
:
As you can see, pdo_mysql and mysqli are installed for both but xdebug is installed only for dev.
Thank you for reading, I hope this helps π