Quando um segundo de parada custa uma fortuna
\n\nImagine: você está atualizando uma loja virtual em PHP, enviando uma nova versão via FTP, e nesse momento o site fica fora do ar por 5 minutos. Cinco minutos são 300 segundos. Nesse tempo, 100 clientes em potencial vão para a concorrência, e você perde não só dinheiro, mas também reputação. Essa dor é familiar?
\n\nNo mundo atual, onde os usuários não perdoam erros, o deploy PHP com zero downtime não é um luxo, mas uma necessidade. Mas como implementar uma implantação contínua e sem interrupções se sua stack é PHP, Nginx e vários servidores? Vamos descobrir com exemplos reais.
\n\nPor que o PHP é mais desafiador do que parece?
\n\nAo contrário de Node.js ou Python, o PHP não suporta multithreading no sentido clássico. Cada requisição é processada por um processo separado do PHP-FPM. Isso impõe limitações: você não pode simplesmente "recarregar" o código sem perder as sessões atuais. No entanto, essa mesma característica nos dá um superpoder — a capacidade de alternar o tráfego entre versões de forma suave.
\n\nPrincipais problemas ao fazer deploy de PHP:
\n- \n
- Conexões interrompidas — o usuário perde dados de formulário ou a sessão \n
- Cache sujo — o código antigo retorna dados de um cache desatualizado \n
- Migrações quebradas — a nova versão do banco de dados não é compatível com o código antigo \n
Para evitar essas armadilhas, usamos estratégias comprovadas. E sim, o deploy com zero downtime não é mágica, é um plano bem definido.
\n\nEstratégia nº 1: Blue-Green Deployment
\n\nA maneira mais confiável é manter duas cópias completas da aplicação: a "azul" (atual) e a "verde" (nova). O Nginx atua como balanceador de carga.
\n\nComo funciona na prática
\nSuponha que você tenha dois servidores: app1.exemplo.com (blue) e app2.exemplo.com (green). Ambos rodam PHP-FPM. No momento, o blue está ativo. Você faz o deploy da nova versão no green, testa e, em seguida, redireciona o Nginx para o green.
Exemplo de configuração do Nginx para a alternância:
\n\n# nginx.conf\nupstream php_backend {\n # Inicialmente, blue ativo\n server app1.exemplo.com:9000 weight=1; # blue\n server app2.exemplo.com:9000 weight=0; # green (desligado)\n}\n\nserver {\n listen 80;\n server_name minhaloja.com;\n\n location ~ \\.php$ {\n fastcgi_pass php_backend;\n include fastcgi_params;\n fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;\n }\n}\n\n\nApós o deploy no green, alteramos os pesos:
\n\n# Após o deploy — redireciona o tráfego\nupstream php_backend {\n server app1.exemplo.com:9000 weight=0; # blue (desligado)\n server app2.exemplo.com:9000 weight=1; # green (ativo)\n}\n\n\nRecarregue o Nginx sem queda: nginx -s reload. Todas as conexões atuais são finalizadas corretamente, e as novas vão para o green. Deploy PHP com zero downtime garantido!
Prós e contras
\nPrós: alta disponibilidade total, é possível reverter rapidamente (basta restaurar os pesos).
\nContras: requer o dobro de recursos (servidores ou contêineres).
Estratégia nº 2: Rolling Update (atualização gradual)
\n\nSe o orçamento é limitado, use o rolling update. A ideia: atualizar os servidores PHP um por um, sem desligar os outros. Os usuários não percebem a parada, pois o Nginx redireciona as requisições para os servidores ativos.
\n\nImplementação com PHP-FPM
\nSuponha que você tenha 3 servidores com PHP-FPM. Retiramos cada um da rotação, atualizamos o código e o colocamos de volta.
\n\nPasso 1: Remova o servidor do balanceador (graceful shutdown):
\n\n# No servidor que está sendo atualizado\nsudo systemctl stop php8.1-fpm\n# O Nginx para de enviar requisições para este servidor, pois ele fica indisponível\n\n\nPasso 2: Atualize o código (via git pull, rsync ou Docker).
\n\nPasso 3: Inicie o PHP-FPM novamente:
\n\nsudo