Metade dos deploys que eu vejo dar errado não tem nada de exótico: é comando na ordem errada. Compilou antes de subir o código, rodou setup:upgrade depois do di:compile, esqueceu o estático. O site volta com admin em branco ou CSS sumido e a pessoa culpa o Magento.
A sequência abaixo é a que eu rodo em loja de cliente. Ela pressupõe modo production ligado e um servidor só — que é a realidade da maior parte das lojas brasileiras em Open Source.
A sequência, num servidor só
php bin/magento maintenance:enable --ip=203.0.113.10
composer install --no-dev --optimize-autoloader
php bin/magento setup:upgrade
php bin/magento setup:di:compile
php bin/magento setup:static-content:deploy pt_BR
php bin/magento cache:flush
php bin/magento maintenance:disableDuas coisas para reparar.
A primeira é o --ip. Sem ele, você também leva 503 na cara e não consegue testar nada antes de abrir a loja. O comando aceita repetir a opção — --ip=203.0.113.10 --ip=203.0.113.11 — e o que ele faz é gravar var/.maintenance.ip ao lado do var/.maintenance.flag. Quem está na lista navega normal enquanto o resto do mundo vê a página de manutenção.
A segunda é a posição do setup:upgrade: depois do composer install e antes do di:compile. Ele é quem roda schema patch e data patch dos módulos novos. Compilar antes disso é compilar um código que ainda não terminou de existir.
Se a sua loja não está em modo production, o static-content:deploy vai recusar rodar e pedir -f. Isso é sinal, não obstáculo: loja de verdade fica em production.
Quando entra o --keep-generated
O setup:upgrade apaga generated/code/ antes de subir. A própria descrição da opção diz: prevents generated files from being deleted. We discourage using this option except when deploying to production.
Ou seja: --keep-generated só faz sentido quando o código já veio compilado de outro lugar. É o cenário de pipeline, em que uma máquina de build faz o trabalho pesado e produção só recebe o pacote:
php bin/magento maintenance:enable --ip=203.0.113.10
php bin/magento app:config:import
php bin/magento setup:upgrade --keep-generated
php bin/magento cache:flush
php bin/magento maintenance:disableRepare que aqui não tem di:compile nem static-content:deploy: eles rodaram no build. Se você usa --keep-generated num servidor onde ainda vai compilar depois, a opção não serve para nada — e se usa sem ter compilado em lugar nenhum, a loja sobe sem interceptor e quebra.
config.php e env.php fazem coisas diferentes
Esses dois arquivos confundem muita gente na hora do deploy, e a diferença é curta:
| Arquivo | O que guarda | Vai pro Git? |
|---|---|---|
app/etc/config.php | lista de módulos e configuração compartilhada entre os ambientes | sim |
app/etc/env.php | banco, Redis, cache, chave de criptografia e o que é sensível | não |
Quem versiona o config.php ganha o app:config:import no deploy: ele aplica no banco o que mudou no arquivo. Quem não versiona pode pular esse passo — mas aí cada ambiente precisa ser configurado na mão pelo admin.
Uma coisa que vale saber antes de apanhar: configuração que está no config.php aparece travada no admin. Não é bug.
Perguntas rápidas
Preciso mesmo de modo de manutenção se o deploy é rapidinho?
Precisa. Entre o setup:upgrade e o di:compile a loja fica num estado em que o banco já mudou mas o código compilado ainda não. Pedido feito nessa janela pode gravar errado.
Posso rodar composer install com a loja no ar?
Pode, mas não recomendo. O composer troca arquivos dentro de vendor enquanto requisições estão lendo esses mesmos arquivos, e você colhe erro de classe não encontrada em cliente real.
E se eu esquecer o static-content:deploy?
Em modo production o Magento não gera arquivo estático sob demanda. A loja volta sem CSS, sem JS e sem imagem de tema até você rodar o comando e limpar o cache.
Pra conferir na fonte
- Configuration files and deployment: technical details — Adobe Experience League
- Enable or disable maintenance mode — Adobe Experience League
- Static view files deployment — Adobe Experience League
- Perform the upgrade — Adobe Experience League