Le WordPress d'aujourd'hui, décodé pour les développeurs

Outils & workflow

Réordonner les couches d’un Dockerfile WordPress pour rebâtir plus vite

Réorganiser les instructions d'un Dockerfile pour que les couches qui changent rarement soient mises en cache en premier accélère nettement les reconstructions. Diagnostic avant/après chiffré.

Par WordPress Développement • 14 février 2024 • 4 min de lecture • Aucun commentaire
Réordonner les couches d'un Dockerfile WordPress pour rebâtir plus vite

4 minutes et 10 secondes, systématiquement, pour reconstruire une image Docker après la moindre modification d’un fichier PHP du thème — alors que ni les dépendances Composer, ni les paquets système, ni rien d’autre n’avait changé. Ce temps de reconstruction, mesuré sur la pipeline de déploiement continu d’un projet WordPress conteneurisé, s’est réduit à 18 secondes après une simple réorganisation des instructions du Dockerfile.

Docker construit une image couche par couche, chaque instruction du Dockerfile produisant une couche mise en cache. Tant que le contenu d’une instruction et de celles qui la précèdent reste identique, Docker réutilise la couche en cache plutôt que de la reconstruire. Mais dès qu’une instruction change, cette couche et toutes celles qui la suivent doivent être reconstruites, même si leur contenu propre n’a pas changé.

Le Dockerfile fautif, ligne par ligne

Le Dockerfile initial copiait l’intégralité du code source du projet avant d’installer les dépendances Composer :

FROM php:8.2-fpm

COPY . /var/www/html
WORKDIR /var/www/html

RUN composer install --no-dev --optimize-autoloader

Avec cet ordre, toute modification d’un fichier du projet — même un simple fichier PHP du thème, sans rapport avec les dépendances — invalide la couche COPY . /var/www/html, et donc également la couche RUN composer install qui la suit, puisque Docker ne peut plus garantir que le contenu sur lequel composer install s’exécute est identique à la dernière construction. L’installation complète des dépendances, y compris le téléchargement des paquets non déjà présents localement, se relance à chaque fois.

La réorganisation qui change tout

La correction sépare la copie des fichiers de dépendances de la copie du reste du code source :

FROM php:8.2-fpm

WORKDIR /var/www/html

COPY composer.json composer.lock ./
RUN composer install --no-dev --optimize-autoloader --no-scripts --no-autoloader

COPY . .
RUN composer dump-autoload --optimize
L'essentiel à retenir : Docker met en cache chaque couche mais invalide tout à partir de la première modifiée ; L'ordre des instructions détermine directement la portée de cette invalidation ; Séparer dépendances et code applicatif réduit le temps de reconstruction de façon mesurable

Avec cet ordre, la couche RUN composer install ne dépend plus que du contenu de composer.json et composer.lock. Tant que ces deux fichiers ne changent pas — ce qui est le cas pour la grande majorité des modifications quotidiennes portant sur le code applicatif — Docker réutilise la couche en cache et saute entièrement l’installation des dépendances, ne reconstruisant que la copie du code source et la régénération de l’autoloader, une opération nettement plus rapide.

Mesurer l’impact réellement

La mesure a été effectuée en modifiant un unique fichier PHP du thème puis en relançant une construction complète de l’image, dans les mêmes conditions matérielles, avant et après réorganisation :

ÉtapeAvant réorganisationAprès réorganisation
Copie des fichiers2 s2 s
Installation Composer3 min 55 s0 s (couche en cache)
Régénération autoloaderinclus ci-dessus16 s
Total4 min 10 s18 s

Pourquoi ce gain compte sur une pipeline de déploiement continu

Sur un projet où chaque poussée de code déclenche une reconstruction de l’image dans la chaîne d’intégration continue, ce gain se répercute directement sur le temps d’attente avant chaque déploiement. À raison d’une dizaine de constructions par jour ouvré sur ce projet, l’économie cumulée représentait plus d’une demi-heure d’attente évitée quotidiennement pour l’équipe, sans compter l’économie de ressources de calcul sur les serveurs d’intégration continue.

Le même principe s’applique aux dépendances front-end

Le même raisonnement vaut pour un package.json et les dépendances Node.js d’un thème à blocs : copier package.json et le fichier de verrouillage avant le reste du code, installer les dépendances, puis copier le code source restant, préserve le cache de la même façon pour les modifications qui ne touchent pas aux dépendances front-end.

Ce qui reste à surveiller malgré tout

Cette réorganisation optimise le cas le plus fréquent — une modification du code sans changement de dépendances — mais toute modification de composer.json ou composer.lock continue légitimement d’invalider la couche d’installation, comme il se doit. Le gain de temps ne dispense pas non plus de choisir une image de base adaptée et de limiter le nombre de couches inutiles ailleurs dans le fichier.

En résumé

Réordonner les instructions d’un Dockerfile pour isoler les fichiers de dépendances du reste du code source ne demande aucune modification du code applicatif lui-même, seulement une meilleure compréhension du mécanisme de cache par couches de Docker. Le gain mesuré ici, d’un facteur supérieur à dix sur le temps de reconstruction, illustre à quel point cet ordre, souvent négligé lors de la première écriture d’un Dockerfile, mérite d’être revu systématiquement.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Partager :

À propos de l'auteur

WordPress Développement

Développeur WordPress, passionné par Elementor, le FSE et l’automatisation par IA.

Voir tous ses articles

Dans la même veine

À lire aussi