Deploy réussi. Puis erreur 500 : classe introuvable. Quelqu'un a lancé composer update directement sur le serveur, la version PHP en ligne de commande est en 8.1 alors que PHP-FPM tourne en 8.2, et le fichier lock n'était pas commité dans le dépôt. Composer en production n'est pas un gestionnaire de packages en direct — c'est un installateur reproductible à partir d'un lock figé, validé en amont.
Cette scène se répète chaque semaine sur des projets Laravel, Symfony ou PHP sur mesure. La bonne nouvelle : le parcours correct tient en quelques règles simples. La mauvaise : une seule exception suffit à transformer un déploiement en loterie.
install vs update : la règle d'or
La distinction entre composer install et composer update n'est pas syntaxique — elle sépare deux mondes.
| Commande | Où l'exécuter | Effet |
|---|---|---|
composer update | Local ou CI de développement | Recalcule les versions selon composer.json |
composer install | CI de build ou production | Reproduit exactement le lock commité |
install --no-dev | Production | Exclut les dépendances require-dev |
install -o / --optimize-autoloader | Production | Autoloader PSR optimisé pour les performances |
composer updateen production, c'est tirer au sort les versions qui casseront le paiement ce soir.
En développement, vous mettez à jour délibérément, vous testez, vous commitez le nouveau lock. En production, vous installez ce qui a déjà été validé — rien de plus, rien de moins.
Pipeline de déploiement recommandé
Option A — build en intégration continue, déploiement d'artefact. L'intégration continue exécute composer install --no-dev -o puis les tests. Elle archive la release (code plus vendor, ou vendor séparé). La production extrait l'artefact et redémarre les services — sans lancer Composer sur le serveur live. C'est l'approche préférable dès que le trafic ou l'équipe dépasse une personne.
Option B — Composer sur le serveur. Vous récupérez un tag Git immuable, vous lancez composer install --no-dev -o --no-interaction, puis migrations, vidage de cache et rechargement de PHP-FPM. Acceptable pour de petits projets, mais fragile si la mémoire serveur est limitée ou si le réseau est instable.
Pièges fréquents en production
PHP CLI différent de PHP-FPM : une extension manquante en ligne de commande bloque l'installation ou génère un autoloader incompatible avec le runtime web.
Mémoire insuffisante : les gros projets Symfony ou Laravel consomment plusieurs centaines de mégaoctets lors de l'installation. Prévoyez l'intégration continue ou une limite mémoire adaptée.
Permissions incorrectes : un dossier vendor modifiable par l'utilisateur web devient une faille de sécurité.
Fuite de packages de développement : oublier --no-dev expose PHPUnit ou d'autres outils si la configuration web est mal verrouillée.
Configuration platform : le champ config.platform.php dans composer.json aligne la résolution des dépendances sur la version cible, même si la machine locale est plus récente.
Ce que l'hébergeur doit permettre
Vérifiez que Composer 2.x est disponible en SSH, que la version PHP en ligne de commande correspond à PHP-FPM, que Git ou un hook de déploiement est accessible, et que la mémoire suffit pour une installation — ou que l'hébergeur accepte le déploiement d'artefacts sans Composer côté serveur.
Pour les étapes post-Composer, consultez nos guides Symfony et Laravel en production.
Le sommet : Composer fige, il ne décide pas en prod
Décider et avancer sans angle mort
Commitez le fichier composer.lock dans le dépôt et traitez toute modification comme un changement de code à tester. Configurez l'intégration continue pour exécuter composer install --no-dev -o suivi des tests avant tout déploiement. Alignez PHP CLI et PHP-FPM sur la même version et les mêmes extensions. Préférez le déploiement d'artefact dès que le trafic ou l'équipe le justifie. Documentez la commande exacte utilisée en production pour que personne n'improvise un update un vendredi soir.
Questions fréquentes
Faut-il lancer composer update en production ?
Non. La production exécute composer install depuis un fichier lock commité dans le dépôt. La commande update recalcule de nouvelles versions de dépendances — elle est réservée à l'environnement de développement ou à l'intégration continue, après exécution des tests automatisés.
Pourquoi --no-dev en prod ?
PHPUnit et les outils de développement augmentent la surface d'attaque et la taille du dossier vendor. Ils ne doivent pas être présents sur un serveur en production, où chaque package superflu peut devenir une porte d'entrée ou un goulet de déploiement.
composer.lock doit-il être versionné ?
Oui pour les applications (Laravel, Symfony, projet sur mesure). Non pour les bibliothèques Composer publiées. Pour un site ou une application, le lock garantit la reproductibilité entre développeurs, intégration continue et production.
Erreur mémoire composer install ?
Vous pouvez temporairement lever la limite avec COMPOSER_MEMORY_LIMIT=-1 ou ajouter du swap. Mieux encore : exécuter l'installation en intégration continue et déployer un artefact contenant le dossier vendor.
En production, Composer répète — il n'improvise pas. Si le lock est absent, le déploiement aussi.