Você roda o composer require de um módulo novo, o resolvedor começa a pensar e vem o fatal:
PHP Fatal error: Allowed memory size of 536870912 bytes exhaustedA reação automática é abrir o php.ini e subir o memory_limit. Funciona, mas você acabou de aumentar o limite do site inteiro por causa de um comando que roda uma vez por mês. Tem jeito melhor, e é documentado pelo próprio Composer.
A variável que resolve
O Composer lê uma variável de ambiente só dele:
COMPOSER_MEMORY_LIMIT=-1 composer updateO -1 é ilimitado. Vale para aquele comando e some quando o comando termina. Se você preferir não depender da variável, dá para passar o limite direto para o PHP, já que o composer é um phar:
php -d memory_limit=-1 /usr/local/bin/composer updateConfira o caminho com which composer antes de copiar essa linha.
Duas coisas que a documentação do Composer diz e quase ninguém sabe. A primeira: o Composer já sobe o memory_limit para 1.5G sozinho. Se ele estourou mesmo assim, o seu projeto está pedindo mais do que isso — o que é normal em Magento com trinta módulos de terceiro. A segunda: se você ainda está no Composer 1, atualize. O Composer 2 usa bem menos memória e o time recomenda a 2.2.0 para cima.
Para saber com quanto você está trabalhando agora:
php -r "echo ini_get('memory_limit').PHP_EOL;"
php --iniO php --ini é o comando mais útil dos dois: ele mostra qual arquivo o PHP de linha de comando está lendo. Em servidor com php-fpm, esse arquivo é outro, diferente do que serve a loja. Muita gente edita o php.ini errado e jura que não adiantou nada.
Os valores que a Adobe pede
Se você vai fixar o valor no php.ini do CLI em vez de usar a variável, use os números da Adobe. Não são chute:
| Situação | memory_limit |
|---|---|
| Compilar código ou fazer deploy de estático | 1G |
| Debug | 2G |
| Rodar testes | 3G a 4G |
O próprio Magento também tem opinião. O PhpReadinessCheck, que roda no instalador, dá erro abaixo de 756M e aviso abaixo de 2G. Ou seja: 2G no CLI é o número que deixa todo mundo quieto.
E tem o lado do hardware. A página de requisitos avisa que atualizar aplicação e extensões pode precisar de até 2 GB de RAM, e que em máquina com menos que isso você deve criar um arquivo de swap, senão o upgrade falha.
Vale reforçar: esses números são para o php.ini do CLI. Não copie memory_limit = -1 para o pool do php-fpm. Lá, um limite alto por worker é o caminho mais curto para o servidor começar a matar processo em horário de pico.
Onde a variável não ajuda
A própria documentação do Composer põe a ressalva: esses ajustes resolvem a memória do Composer. Processo filho e comando externo continuam com o limite deles. No Magento isso dói exatamente aqui:
php -d memory_limit=-1 bin/magento setup:di:compile
php -d memory_limit=-1 bin/magento setup:static-content:deploy pt_BR -j 4O COMPOSER_MEMORY_LIMIT não alcança o bin/magento, porque é outro processo PHP. Se o seu deploy morre no di:compile e não no composer install, o problema nunca foi do Composer.
Outros dois casos que aparecem muito em loja brasileira hospedada em compartilhado:
- cPanel com proteção de fork bomb ligada. O Composer trava ou morre com mensagem de memória mesmo tendo memória sobrando. É limite de processo, não de RAM. A documentação do Composer cita esse caso pelo nome.
- O kernel matando o processo. Com
memory_limit=-1numa VPS de 2 GB, o PHP pede memória até o sistema derrubar tudo. Aí não sai fatal do PHP, sai Killed na tela. Confirme comdmesg | grep -i "killed process". Nesse caso, o que falta é swap ou RAM, e a variável não vai salvar.
O que eu faço em produção: memory_limit = 2G no php.ini do CLI, COMPOSER_MEMORY_LIMIT=-1 só quando um update específico reclamar, e swap configurado em qualquer máquina com menos de 4 GB. Com isso eu não mexo nesse assunto há anos.
Perguntas rápidas
Posso deixar memory_limit = -1 fixo no php.ini?
No php.ini do CLI, dá para viver com isso. No pool do php-fpm que atende a loja, não. Sem teto, um único request com problema consome a RAM do servidor e derruba o site inteiro.
Como sei se o php.ini que editei é o certo?
Rode php --ini na mesma sessão em que você roda o composer. Ele imprime o Loaded Configuration File. Se o caminho tiver fpm ou apache2 no meio, é o php.ini errado.
O composer install em produção também precisa disso?
Costuma precisar bem menos, porque ele só lê o composer.lock e não resolve dependência. Se o install estoura memória, quase sempre é o lock desatualizado forçando resolução, ou memória de verdade faltando na máquina.
Pra conferir na fonte
- Troubleshooting: memory limit errors — Composer
- Required PHP settings — Adobe Experience League
- System requirements — Adobe Experience League
- PhpReadinessCheck.php — GitHub