Un composer update lancé sur un petit serveur s'arrête sur Fatal error: Allowed memory size of ... bytes exhausted. La solution immédiate tient en une variable : COMPOSER_MEMORY_LIMIT=-1. La bonne pratique évite le problème : résoudre les dépendances en local avec composer update, envoyer le composer.lock, et ne lancer que composer install sur le serveur, qui consomme nettement moins de mémoire. Rien de propre à Laravel : c'est vrai pour tout projet PHP.
Que fait Composer de la limite mémoire de PHP ?
Composer 2 la relève déjà de lui-même. Le code de son lanceur le dit en clair :
// bin/composer (extrait du code de Composer 2.10.3) // Increase memory_limit if it is lower than 1.5GB if ($memoryLimit != -1 && $memoryInBytes($memoryLimit) < 1024 * 1024 * 1536) { @ini_set('memory_limit', '1536M'); }
Nous l'avons vérifié en affichant la limite vue par Composer, avec PHP réglé sur 128 Mo :
| Commande | Limite pendant Composer |
|---|---|
composer ... |
1536M |
COMPOSER_MEMORY_LIMIT=-1 composer ... |
-1 (aucune limite) |
COMPOSER_MEMORY_LIMIT=512M composer ... |
512M |
php -d memory_limit=1G composer.phar ... |
1536M |
php -d memory_limit=2G composer.phar ... |
2G |
php -d memory_limit=-1 composer.phar ... |
-1 |
Deux enseignements : une limite PHP plus basse que 1,5 Go est remontée, une limite plus haute est respectée ; et COMPOSER_MEMORY_LIMIT passe avant tout, même pour fixer une valeur plus basse. La documentation le résume : "If set, the value is used as php's memory_limit."
Comment lever la limite pour une commande ?
Les deux formes données par la documentation de Composer :
COMPOSER_MEMORY_LIMIT=-1 composer update php -d memory_limit=-1 composer.phar update
Pour connaître la limite de PHP en ligne de commande, la documentation propose :
php -r "echo ini_get('memory_limit').PHP_EOL;"
Composer relève sa limite avec ini_set(). Si l'hébergeur a mis cette fonction dans disable_functions, la limite est restée à 128 Mo dans notre test, même avec COMPOSER_MEMORY_LIMIT=-1. Seul php -d memory_limit=-1 composer.phar a fonctionné.
Pourquoi l'erreur arrive surtout avec composer update ?
Parce que update doit trouver une combinaison de versions compatible pour tout le projet ("resolve all dependencies of the project"), alors qu'install lit les versions exactes du composer.lock ("it will use the exact versions from there"). Mesures relevées avec l'option --profile de Composer 2.10, sur deux projets :
| Projet | Pic update |
Pic install depuis le lock |
|---|---|---|
laravel/framework seul (75 paquets) |
39 Mo | 22 Mo |
| Application Laravel avec Filament et Livewire (149 paquets) | 89 Mo (résolution seule, --no-install) |
39 Mo |
Avec une limite volontairement basse, update s'est arrêté : Allowed memory size of 33554432 bytes exhausted (32 Mo) pour le gros projet.
Quelle méthode adopter sur un serveur de production ?
Faites les mises à jour en local ou dans votre intégration continue, testez, puis versionnez composer.lock. Sur le serveur, installez uniquement ce qui est figé :
composer install --no-dev --optimize-autoloader
--no-dev ignore les paquets de développement, --optimize-autoloader génère un chargement de classes plus rapide. Vous gagnez en mémoire, et le serveur reçoit exactement les versions que vous avez testées.
La limite à -1 suffit-elle sur un petit serveur ?
Non : -1 retire la limite de PHP, il ne crée pas de mémoire. Dans un conteneur limité à 64 Mo, COMPOSER_MEMORY_LIMIT=-1 composer update sur le gros projet a été tué par le système (code de sortie 137), sans aucun message de PHP. Pour l'erreur proc_open(): fork failed, la documentation de Composer pointe le même manque de mémoire, "because the VPS runs out of memory and has no Swap space enabled", et conseille de vérifier avec free -m.
Nous appliquons cette méthode sur les applications que nous hébergeons et maintenons : aucune résolution de dépendances en production. L'ordre des commandes après l'installation compte aussi, nous le détaillons dans env() renvoie null après un déploiement.
- Composer 2 monte déjà la limite à 1,5 Go si PHP est réglé plus bas.
COMPOSER_MEMORY_LIMIT=-1ouphp -d memory_limit=-1 composer.pharpour lever la limite ponctuellement.updateconsomme plus qu'install: résoudre en local,composer install --no-dev --optimize-autoloadersur le serveur.-1ne remplace pas la mémoire du serveur.
Testé avec Composer 2.10.3 et PHP 8.3.35 sous Linux (Docker).
Questions fréquentes
Comment savoir quelle version de Composer est installée ?
Avec composer --version. La documentation de Composer demande, en cas d'erreur de mémoire, de vérifier d'abord que vous utilisez Composer 2, si possible 2.2.0 ou plus récent.
Faut-il versionner le fichier composer.lock ?
Pour une application, oui : c'est lui que composer install lit pour installer les versions exactes testées en local. Sans lui, le serveur devrait résoudre les dépendances, comme un composer update.
À quoi sert --no-dev sur le serveur ?
Il n'installe pas les paquets de require-dev (outils de test, de débogage) et ignore les règles autoload-dev. Le serveur reçoit moins de paquets, inutiles en production.