Fix rápido

CSS e imagens dando 404 depois do deploy no Magento 2

O Magento em produção não gera arquivo estático na hora do acesso. Se não está no disco, é 404 — e a culpa quase sempre é do lixo que ficou do deploy passado.

Por Roger Takemiya · Publicado em · 5 min de leitura

Deploy terminou, você abre a loja e ela está sem estilo nenhum — texto preto no fundo branco, menu virando lista. O F12 mostra dezenas de 404 em URLs do tipo /static/version1756600000/frontend/Magento/luma/pt_BR/css/styles-m.css.

Antes de suspeitar do nginx ou do CDN, olhe o disco. Em nove de cada dez casos o arquivo simplesmente não está lá.

Por que dá 404 e o que é aquele "version" na URL

Em modo developer, o Magento monta o arquivo estático na hora em que o navegador pede, passando pelo pub/static.php. Em modo production, esse mesmo arquivo devolve 404 de propósito: o Magento\Framework\App\StaticResource confere o modo e corta antes de gerar qualquer coisa. Em produção só existe o que o setup:static-content:deploy já escreveu no disco.

Antes de apagar qualquer coisa, entenda o version1756600000 no meio da URL. O número sai do deployed_version.txt, que fica na raiz do pub/static — a declaração dele está no app/etc/di.xml do core, apontando para o diretório STATIC_VIEW. E esse trecho existe só na URL: não tem pasta nenhuma com esse nome no disco. Quem tira ele do caminho é uma regra de reescrita — RewriteRule ^version.+?/(.+)$ $1 [L] no pub/static/.htaccess, ou o location ~ ^/static/version\d*/ do nginx.conf.sample que vem no próprio Magento.

Isso te dá um teste de dois segundos que separa os dois problemas possíveis. Pegue a URL que deu 404 e acesse de novo, sem o version.../ no meio:

  • as duas dão 404 → o arquivo não está no disco. É deploy incompleto ou sobra do deploy anterior, e o resto desta dica resolve;
  • a sem o número responde 200 → o arquivo está lá e falta a regra de reescrita no servidor. Aí o problema é de configuração de nginx ou Apache, não do Magento.
cat pub/static/deployed_version.txt
ls pub/static/frontend/

Limpe o pub/static do jeito certo

A instrução da Adobe é literal: apague o conteúdo do pub/static, menos o .htaccess. Esse arquivo não pode sumir, senão o Apache passa a servir coisa que não devia.

php bin/magento maintenance:enable
find pub/static -mindepth 1 -maxdepth 1 ! -name '.htaccess' -exec rm -rf {} +

Repare no rm -rf pub/static que não aparece aí. Apagar a pasta inteira leva o .htaccess junto e, dependendo de como o usuário do deploy está configurado, a pasta volta com dono errado.

Se a sua instalação usa symlink — é o padrão em ambiente de cloud e em quem faz deploy com release em pasta datada — sobra link quebrado apontando para lugar nenhum. O próprio artigo de suporte da Adobe manda limpar assim:

find pub/static/ -maxdepth 1 -type l -delete

Eu limpo também o var/view_preprocessed, que guarda o LESS já compilado. Não é obrigatório, mas quando o problema é estilo antigo grudado, é ele.

rm -rf var/view_preprocessed/*

Gere de novo e confira

Agora sim:

php bin/magento setup:static-content:deploy pt_BR en_US
php bin/magento cache:flush
php bin/magento maintenance:disable

Um detalhe que quase todo tutorial copia errado: o -f. A descrição oficial da opção é deploy files in any mode — ela existe porque, sem ela, o comando só roda em modo production. Se a sua loja já está em production, você não precisa do -f. Se está em default ou developer e você quer materializar os arquivos, aí sim:

php bin/magento setup:static-content:deploy -f pt_BR

Terminou, confira três coisas antes de tirar a manutenção:

  • o número novo: cat pub/static/deployed_version.txt;
  • se a pasta do seu tema existe mesmo, com ls pub/static/frontend/;
  • se o dono dos arquivos é o usuário do PHP-FPM, e não o root — rodar o deploy como root é o jeito clássico de trocar 404 por 403.

Depois teste pelo terminal, sem cache de navegador atrapalhando:

curl -sS -o /dev/null -w "%{http_code}\n" "https://sualoja.com.br/static/version$(cat pub/static/deployed_version.txt)/frontend/Magento/luma/pt_BR/css/styles-m.css"

Quando não é o pub/static

Se os arquivos estão no disco, com o dono certo, e o 404 continua, aí a lista muda:

  • Falta a regra de reescrita. É a suspeita número um depois de migração de servidor. Compare o seu nginx.conf com o nginx.conf.sample do Magento, ou confira se o pub/static/.htaccess existe e se o AllowOverride do Apache está permitindo que ele valha.
  • Sign Static Files. É o dev/static/sign, em Stores > Configuration > Advanced > Developer, e a tela só aparece em modo developer. Desligar apenas tira o número da URL: não cria arquivo que não existe.
  • Cache de página com HTML velho. O Varnish ou o full page cache guardaram a página apontando para a versão anterior. Um cache:flush resolve; se tem Varnish, limpe nele também.
  • CDN. Mesma história, uma camada acima. Invalide o caminho /static/.

E tem uma válvula de escape para quando a loja está quebrada no ar e você precisa de tempo: a chave static_content_on_demand_in_production no app/etc/env.php faz o static.php voltar a gerar arquivo sob demanda mesmo em produção. Use para destravar e desligue depois: cada arquivo faltando vira uma passada completa pelo PHP, a cada acesso.

Perguntas rápidas

Posso apagar o pub/static com a loja no ar?

Pode, mas quem entrar no meio do processo vai ver a loja quebrada até o deploy terminar. Por isso eu ligo a manutenção antes e desligo depois. Em loja com movimento, faça isso de madrugada ou use uma pasta de release nova com troca de symlink no final.

Preciso rodar o setup:upgrade junto?

Não. Gerar arquivo estático é independente de migração de banco. Só rode o setup:upgrade se você acabou de instalar ou atualizar módulo, porque aí o conteúdo estático do módulo novo também precisa ser publicado.

Depois de limpar tudo, o site fica quanto tempo sem CSS?

O tempo do próprio static-content:deploy, que varia muito com a quantidade de temas e idiomas. Em loja com um tema e dois idiomas costuma ficar em poucos minutos; com vários temas e locales, pode passar de vinte.

Pra conferir na fonte

  1. Deploy static view files — Adobe Experience League
  2. The path to deployed_version.txt is not writable — Adobe Commerce Knowledge Base
  3. Developer configuration reference — Adobe Experience League
  4. app/etc/di.xml (deployed_version.txt) — GitHub

deploy static fix

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