Aller au contenu principal
Making DigitalMaking Digital
Note technique

Composer et memory_limit : corriger l'erreur de mémoire

En bref

Composer 2 relève déjà la limite mémoire de PHP à 1,5 Go si elle est plus basse. Pour la lever complètement, COMPOSER_MEMORY_LIMIT=-1 ou php -d memory_limit=-1 composer.phar suffisent. Le plus sûr reste de lancer composer update en local, de versionner composer.lock et de n'exécuter que composer install sur le serveur, qui consomme moins de mémoire.

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 :

PHP
// 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 :

Terminal
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 :

Terminal
php -r "echo ini_get('memory_limit').PHP_EOL;"
Hébergement où ini_set est désactivé

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é :

Terminal
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.

À retenir
  • Composer 2 monte déjà la limite à 1,5 Go si PHP est réglé plus bas.
  • COMPOSER_MEMORY_LIMIT=-1 ou php -d memory_limit=-1 composer.phar pour lever la limite ponctuellement.
  • update consomme plus qu'install : résoudre en local, composer install --no-dev --optimize-autoloader sur le serveur.
  • -1 ne 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.

Making Digital

Nous connectons les logiciels des PME, automatisons leurs tâches répétitives et créons des assistants IA, depuis 2010. Nos articles partent de nos projets réels.

Notre parcours
Une question sur ce sujet ?

Parlons-en 30 minutes.

Vous saurez si votre problème se règle, comment, et en combien de temps. Sans engagement.

Un échange de 30 minutes, en visio ou par téléphone

Gratuit, sans engagement. On parle de votre problème, pas de technique.