Docker et PHP : conteneurisation d'applications à un niveau avancé
La conteneurisation d'applications PHP avec Docker a depuis longtemps cessé d'être simplement un outil pratique pour le développement. À un niveau avancé, c'est la clé pour créer des environnements évolutifs, sécurisés et reproductibles. Dans cet article, nous aborderons les techniques qui vous aideront à passer du lancement de base d'un conteneur PHP à une orchestration professionnelle : construction multi-stage, optimisation des images, travail avec Docker Compose pour une architecture microservices et mise en cache avancée.
1. Construction multi-stage : image finale minimale
L'un des principaux problèmes des images Docker standard est leur taille. L'image de base php:8.2-apache pèse plus de 400 Mo, et avec l'installation des extensions, elle atteint 600 Mo ou plus. Pour la production, c'est inacceptable : une image volumineuse se charge plus lentement, prend de la place dans le registre et augmente la surface d'attaque.
La construction multi-stage (multi-stage build) permet de diviser le processus en étapes : une pour la compilation et l'installation des dépendances (avec un ensemble complet d'outils), la seconde pour un environnement d'exécution minimal. L'image finale ne contient que les artefacts compilés et les bibliothèques nécessaires.
Exemple de Dockerfile pour une application Laravel :
# Étape 1 : Compilation et installation des dépendancesFROM composer:latest AS vendorWORKDIR /appCOPY composer.json composer.lock ./RUN composer install --no-dev --optimize-autoloader --no-interaction
# Étape 2 : Compilation des ressources Node (si frontend)FROM node:18-alpine AS frontendWORKDIR /appCOPY package.json package-lock.json ./RUN npm ci --productionCOPY resources/ ./resources/RUN npm run production
# Étape 3 : Image PHP finaleFROM php:8.2-fpm-alpine AS productionRUN docker-php-ext-install pdo_mysql opcacheCOPY --from=vendor /app/vendor /var/www/html/vendorCOPY --from=frontend /app/public/build /var/www/html/public/buildCOPY . /var/www/html
RUN chown -R www-data:www-data /var/www/html/storage /var/www/html/bootstrap/cacheEXPOSE 9000CMD ["php-fpm"]Cette approche réduit la taille de l'image de 500+ Mo à environ 120 Mo. composer:latest et node:18-alpine ne sont utilisés que pendant les étapes de construction et n'entrent pas dans la couche finale.
2. Optimisation de la mise en cache des couches Docker
Chaque instruction dans un Dockerfile crée une couche. Pour accélérer les constructions répétées, il faut placer les couches qui changent rarement le plus tôt possible. Pour un projet PHP, cela signifie :
- Copier
composer.jsonetcomposer.lockavant de copier le code. - Lancer
composer installavant de copier les sources. - Copier le code en dernier.
Exemple d'ordre optimisé des instructions :
FROM php:8.2-fpm-alpine AS baseWORKDIR /var/www/html
# Installer les dépendances système une foisRUN apk add --no-cache $PHPIZE_DEPS \ && docker-php-ext-install pdo_mysql opcache bcmath
# Copier uniquement les fichiers de dépendancesCOPY composer.json composer.lock ./RUN composer install --no-dev --no-interaction --no-scripts --prefer-dist
# Copier le reste du codeCOPY . .
# Générer l'autoload et optimiserRUN composer dump-autoload --optimizeConseil : utilisez .dockerignore pour exclure vendor, .git, node_modules et autres fichiers temporaires du contexte de construction. Cela accélérera le transfert du contexte au démon Docker.
3. Docker Compose pour une architecture microservices
Les applications PHP modernes sont rarement composées d'un seul service. Une architecture typique inclut PHP-FPM, Nginx, Redis, une file d'attente de tâches (RabbitMQ/Beanstalkd) et une base de données. Docker Compose permet de décrire toute l'infrastructure dans un seul docker-compose.yml.
Exemple de configuration pour un microservice PHP :
version: '3.8'services: app: build: context: . target: production