Magento 2 em production mode: como mudar e fazer o deploy
O Magento 2 tem três modos de aplicação, e rodar uma loja no ar em qualquer modo que não seja o production custa velocidade e expõe detalhes que deveriam ficar privados. Trocar de modo é um comando. Fazer o deploy corretamente em production mode, para a loja não quebrar por alguns minutos a cada release, exige um pouco mais de planejamento. Este artigo cobre o que o production mode muda, como trocar e uma sequência de deploy para o Magento Open Source e o Adobe Commerce 2.4.8 que funciona em um único servidor e escala para um pipeline de build de verdade.
Os três modos
- default: o que uma instalação nova usa. Os arquivos estáticos são gerados sob demanda, os erros são registrados mas não exibidos. É um meio-termo que não serve nem para desenvolvimento nem para produção.
- developer: para trabalho local. Código gerado e arquivos estáticos são criados na hora, erros aparecem no navegador e os caches são mais fáceis de manusear. Lento por design.
- production: para lojas no ar. Os arquivos estáticos precisam ser deployados antes, o código gerado precisa ser compilado, os erros só vão para o log e a aplicação nunca tenta gravar em
pub/staticem runtime.
Veja o modo atual com:
bin/magento deploy:mode:show
O modo fica guardado em app/etc/env.php em MAGE_MODE. Também é possível defini-lo na config do web server por uma variável de ambiente, mas mantê-lo no env.php garante que a CLI e o web server sempre concordem.
O que muda no production mode
Conteúdo estático é servido só de pub/static
No production mode o Magento espera que cada tema e locale tenha seus arquivos estáticos em pub/static. Arquivos ausentes não são gerados. Se você esquecer de fazer o deploy de um locale, a loja carrega sem CSS ou JavaScript naquela store view.
O código gerado precisa existir
Interceptors, factories, proxies e a configuração de DI compilada ficam em generated/. No production mode eles precisam ser construídos com o setup:di:compile antes de o código rodar. Se uma classe estiver faltando, você recebe um erro fatal em vez de geração na hora. O guia de código gerado explica o que vai parar nessa pasta.
Os erros não são exibidos
As exceções vão para var/log e var/report. O visitante vê uma página de erro com um número de relatório. É isso que você quer em uma loja no ar.
Algumas configurações do admin ficam escondidas
As configurações de developer em Stores, Configuration, Advanced, Developer não aparecem no production mode. Você as define com bin/magento config:set ou no app/etc/config.php.
Mudando para o production mode
bin/magento deploy:mode:set production
Esse comando ativa o modo de manutenção, limpa o código gerado e os arquivos estáticos, roda a compilação de DI e o deploy do conteúdo estático, e depois desativa o modo de manutenção. Em uma loja no ar isso significa downtime pelo tempo que a compilação e o static deploy levarem, que pode ser de muitos minutos.
Se você já compilou e fez o deploy dos arquivos estáticos por conta própria, use --skip-compilation para trocar só o modo:
bin/magento deploy:mode:set production --skip-compilation
Na prática eu só uso o deploy:mode:set uma vez, quando um projeto passa para o production mode pela primeira vez. Depois disso o modo fica no env.php e cada deploy roda os comandos individuais na ordem certa.
Uma sequência de deploy para um servidor
Esta é a sequência mínima para um release em um único servidor onde você atualiza o código no próprio lugar. Não é zero downtime, mas mantém a janela de manutenção curta e previsível.
git pull
composer install --no-dev --optimize-autoloader
bin/magento maintenance:enable
bin/magento setup:upgrade --keep-generated
bin/magento setup:di:compile
bin/magento setup:static-content:deploy en_US pt_BR -j 4
bin/magento cache:flush
bin/magento maintenance:disable
sudo systemctl reload php8.3-fpm
Algumas notas:
--no-devmantém pacotes de desenvolvimento como o PHPUnit fora de produção.- O
setup:upgradesozinho apaga o código gerado. O--keep-generatedo mantém, o que só faz sentido aqui porque a compilação roda logo depois. - Liste no static content deploy todo locale usado por qualquer store view. Se o admin usa um locale diferente do storefront, inclua-o também.
- O reload do FPM limpa o OPcache quando o
opcache.validate_timestampsestá desligado.
O ponto fraco dessa sequência é que a compilação e o static deploy rodam com a loja em modo de manutenção. Essa é a parte que um pipeline de build elimina.
Tirando o build do deploy
A compilação e o deploy do conteúdo estático não precisam rodar no servidor no ar, e com alguma preparação nem precisam de um banco de dados. Os passos:
1. Faça o dump da config para o config.php
O static content deploy precisa saber quais temas e locales estão em uso. Normalmente ele lê isso do banco. Se você fizer o dump da config relevante para o app/etc/config.php versionado, um servidor de build consegue lê-la do arquivo:
bin/magento app:config:dump scopes themes i18n
Faça commit do config.php atualizado. Valores exportados assim ficam travados no admin, e é essa a ideia. A atribuição de tema e locale passa a fazer parte do código.
2. Construa um artifact
No servidor de build ou runner de CI, a partir de um checkout limpo:
composer install --no-dev --optimize-autoloader
bin/magento setup:di:compile
composer dump-autoload --optimize --apcu
bin/magento setup:static-content:deploy en_US pt_BR -j 4 --area frontend --area adminhtml
O resultado é uma pasta com vendor, generated e pub/static prontos para uso. Empacote como um arquivo compactado.
3. Faça o deploy do artifact
No servidor, descompacte o artifact em uma pasta de release nova, ligue as pastas compartilhadas como pub/media, var e app/etc/env.php, e então decida se o banco precisa de upgrade:
cd /var/www/magento/releases/20261110120000
if ! bin/magento setup:db:status; then
bin/magento maintenance:enable
bin/magento setup:upgrade --keep-generated
fi
bin/magento app:config:import
ln -sfn /var/www/magento/releases/20261110120000 /var/www/magento/current
sudo systemctl reload php8.3-fpm
bin/magento cache:flush
bin/magento maintenance:disable
O setup:db:status devolve um exit code diferente de zero quando há patches de schema ou de dados pendentes. Quando nada mudou no banco, o release sai sem modo de manutenção nenhum. A abordagem completa está no guia de deploy sem downtime, e o guia de CI/CD com GitHub Actions mostra como construir o artifact em um pipeline.
O que quebra no production mode
- Uma store view sem arquivos estáticos. Alguém adicionou um locale no admin mas não ao comando de deploy.
- Código que grava em pub/static em runtime. Algumas extensões antigas fazem isso. Falha ou produz arquivos que o próximo deploy apaga.
- Classes geradas ausentes. Um módulo foi adicionado ou um constructor mudou sem rodar a compilação. O erro cita uma classe que não existe, muitas vezes terminando em
InterceptorouFactory. - Permissões de arquivo erradas. O usuário web precisa conseguir gravar em
var,generated,pub/staticepub/mediadurante o deploy, mas no production mode nada deve precisar de escrita nas pastas de código em runtime. - Cron rodando durante o deploy. Um cron job que começa com o código deployado pela metade pode falhar ou deixar locks. Pare o cron durante a janela de deploy, ou pelo menos faça o deploy quando não houver jobs pesados agendados.
As seções do env.php e do config.php mexidas aqui são explicadas com mais detalhe no guia de env.php e config.php.
FAQ
Como vejo em qual modo o Magento 2 está rodando?
Rode bin/magento deploy:mode:show. O valor fica guardado como MAGE_MODE no app/etc/env.php.
O deploy:mode:set production causa downtime?
Sim, ele ativa o modo de manutenção enquanto compila e faz o deploy do conteúdo estático. Use --skip-compilation se você já rodou esses passos por conta própria.
Posso rodar o setup:static-content:deploy sem banco de dados?
Sim, se antes você fizer o dump de scopes, themes e i18n para o app/etc/config.php com o app:config:dump. O build então lê temas e locales do arquivo.
Por que minha loja carrega sem CSS depois de mudar para o production mode?
Os arquivos estáticos daquele tema ou locale não foram deployados. Adicione o locale que falta ao setup:static-content:deploy e rode de novo.
Atendo como freelancer em Magento e Adobe Commerce, incluindo pipelines de deploy. Se precisar de ajuda com isso, fale comigo.
Artigos relacionados
Deploy do Magento 2 sem downtime em um único servidor
Um deploy sem downtime para o Magento 2.4 em um servidor: build numa pasta de release, compile fora do live, troca de symlink e rollback em segundos.
Pipeline de CI/CD do Magento 2 com GitHub Actions
Monte um pipeline de CI/CD do Magento 2.4.8 no GitHub Actions: auth do Composer, coding standard, PHPStan, testes unitários, build sem banco e deploy atômico.
Ambiente local do Magento 2 com Docker e Warden
Monte um ambiente local do Magento 2.4.8 com Docker e Warden: env-init, o arquivo .env, instalar ou importar um projeto, Xdebug e os comandos do dia a dia.
Backup e restore no Magento 2: o que salvar e como
Como fazer backup e restore de uma loja Magento 2: dumps de banco que importam sem erro, mídia, env.php e a chave de criptografia, cópias offsite e restores testados.