Infra & Deploy

Composer estourando memória no Magento 2: a variável que resolve

O composer update roda três minutos, come a RAM toda e morre. Antes de sair editando php.ini às cegas, tem uma linha que resolve o caso na hora.

Por Roger Takemiya · Publicado em · 4 min de leitura

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 exhausted

A 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 update

O -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 update

Confira 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 --ini

O 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çãomemory_limit
Compilar código ou fazer deploy de estático1G
Debug2G
Rodar testes3G 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 4

O 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=-1 numa 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 com dmesg | 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

  1. Troubleshooting: memory limit errors — Composer
  2. Required PHP settings — Adobe Experience League
  3. System requirements — Adobe Experience League
  4. PhpReadinessCheck.php — GitHub

composer deploy php

Precisa de um orçamento? Ficarei feliz em ajudar. Clique Aqui