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

Outils & workflow

Un lockfile Composer qui dérive entre le poste local et la production

Deux installations censées être identiques peuvent diverger si le lockfile n'est pas la source unique de vérité du déploiement. Diagnostic d'un cas réel et méthode pour le prévenir.

Par WordPress Développement • 10 décembre 2021 • 4 min de lecture • Aucun commentaire
Un lockfile Composer qui dérive entre le poste local et la production

Fatal error: Uncaught Error: Call to undefined method : ce message, apparu en production trois jours après un déploiement jugé sans histoire, a mis plusieurs heures à être expliqué. Aucune modification de code n’avait pourtant été poussée entre-temps. La cause s’est révélée plus subtile qu’un bug applicatif classique : une divergence silencieuse entre les dépendances installées localement et celles réellement déployées en production.

Symptôme : un comportement différent sur deux environnements identiques en apparence

Le code du projet, versionné dans le dépôt Git, était strictement identique entre le poste local où les tests avaient été menés et le serveur de production où l’erreur survenait. Pourtant, une méthode appelée dans le code n’existait tout simplement pas dans la version de la bibliothèque installée en production, alors qu’elle fonctionnait parfaitement en local.

Diagnostic : deux commandes qui ne font pas la même chose

L'essentiel à retenir : Une installation lancée sans le lockfile peut résoudre des versions différentes ; Le symptôme apparaît souvent bien après le déploiement fautif ; La commande install doit toujours primer sur update en production

L’enquête a révélé que le script de déploiement exécutait composer update plutôt que composer install. Cette différence, souvent perçue à tort comme équivalente, ne l’est absolument pas. La commande update recalcule l’arbre complet des dépendances en respectant les contraintes de version du fichier composer.json, sans tenir compte du lockfile existant, puis réécrit ce lockfile avec le résultat obtenu. La commande install, elle, installe strictement les versions déjà figées dans le lockfile présent, sans rien recalculer.

# En production, ce qu'il fallait exécuter :
composer install --no-dev --optimize-autoloader

# Ce qui était exécuté par erreur dans le script de déploiement :
composer update --no-dev

Entre le moment où le lockfile avait été généré en local et le moment du déploiement en production, une contrainte de version assez permissive dans composer.json avait permis à update de résoudre une version plus récente d’une bibliothèque tierce, une version qui avait justement renommé la méthode appelée par le code du projet.

  • Le lockfile généré en local ne sert à rien si le script de déploiement ne l’utilise pas réellement.
  • Une contrainte de version trop permissive dans composer.json laisse la porte ouverte à une résolution différente selon le moment de l’exécution.
  • Le symptôme peut apparaître plusieurs jours après le déploiement fautif, dès qu’une bibliothèque tierce publie une nouvelle version compatible avec la contrainte déclarée.

Correctif : faire du lockfile la seule source de vérité

La correction a consisté à remplacer systématiquement composer update par composer install dans le script de déploiement, en s’assurant que le lockfile versionné dans le dépôt Git soit toujours celui utilisé pour reconstruire l’environnement de production. La commande update n’a désormais plus sa place que sur le poste de développement, lors d’une mise à jour volontaire et testée d’une dépendance.

Prévention : verrouiller le processus autant que les versions

Au-delà de la correction immédiate, une vérification a été ajoutée au script de déploiement pour refuser toute installation si le lockfile ne correspond plus au fichier composer.json présent dans le dépôt, situation que la commande composer install détecte et signale d’elle-même par défaut.

composer validate --no-check-all --strict
composer install --no-dev --optimize-autoloader

Un lockfile qui n’est pas systématiquement respecté au déploiement n’est qu’un fichier de plus dans le dépôt, pas une garantie de reproductibilité.

Un point de vigilance supplémentaire : les dépendances de développement

L’option --no-dev, présente dans la commande corrigée, mérite elle aussi son explication : elle exclut de l’installation les bibliothèques utilisées uniquement pendant le développement, comme les outils de test ou d’analyse statique de code, absents et inutiles en production. Oublier cette option ne provoque pas nécessairement d’erreur immédiate, mais alourdit inutilement l’environnement de production et élargit sa surface d’attaque avec du code qui n’a aucune raison d’y être présent.

Cette vigilance sur le contenu exact de ce qui est installé complète la discipline autour du lockfile : la reproductibilité d’un déploiement ne se limite pas à figer des versions, elle inclut aussi la maîtrise précise de ce qui doit, ou non, se retrouver sur le serveur de production final.

En résumé

Une simple confusion entre composer update et composer install dans un script de déploiement a suffi à faire diverger silencieusement deux environnements censés être identiques. La prévention durable ne repose pas seulement sur la vigilance humaine, mais sur un script de déploiement qui refuse toute installation ne respectant pas strictement le lockfile versionné.

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