Como Diagnosticar e Resolver Erros 502 Bad Gateway do Nginx
O Nginx é um servidor web e proxy reverso poderoso e popular, frequentemente usado para servir conteúdo estático, balancear a carga de tráfego e encaminhar requisições para vários servidores de aplicação upstream, como PHP-FPM, Node.js, Python Gunicorn ou Apache Tomcat. Quando o Nginx encontra um problema ao se comunicar com um desses servidores upstream, ele geralmente responde com um erro "502 Bad Gateway".
Este artigo fornece um guia abrangente, passo a passo, para entender, diagnosticar e resolver erros 502 Bad Gateway do Nginx. Exploraremos as causas comuns, equiparemos você com técnicas práticas de solução de problemas usando ferramentas de linha de comando e ofereceremos soluções acionáveis para colocar seus serviços web de volta ao ar rapidamente. Seja você um administrador de sistema, desenvolvedor ou gerenciando seu próprio servidor, este guia o ajudará a lidar eficazmente com um dos erros mais comuns do Nginx.
Entendendo o Erro 502 Bad Gateway do Nginx
Um erro 502 Bad Gateway indica que o Nginx, atuando como proxy reverso, recebeu uma resposta inválida de um servidor upstream. Isso significa que o Nginx se conectou com sucesso a um servidor upstream, mas recebeu nenhuma resposta, uma resposta incompleta ou uma resposta que não conseguiu entender. Crucialmente, o problema não está no Nginx em si, mas no serviço com o qual o Nginx está tentando se comunicar.
Servidores upstream comuns incluem:
- PHP-FPM: Para aplicações PHP (ex: WordPress, Laravel).
- Gunicorn/uWSGI: Para aplicações Python (ex: Django, Flask).
- Node.js: Para aplicações JavaScript.
- Apache Tomcat: Para aplicações Java.
- Outros servidores web: Como o Apache HTTP Server servindo conteúdo específico.
A falha 502 é um indicador crucial de que o backend da sua aplicação não está funcionando corretamente ou está inacessível para o Nginx.
Diagnóstico Passo a Passo
A chave para resolver um erro 502 é o diagnóstico sistemático. Comece com os culpados mais prováveis e investigue progressivamente.
1. Verifique os Logs de Erro do Nginx Primeiro
Seus logs de erro do Nginx são a principal fonte de informação. Eles geralmente contêm detalhes específicos sobre por que o Nginx não conseguiu se comunicar com o servidor upstream.
- Localização: Geralmente encontrado em
/var/log/nginx/error.log. - Comando: Use
tail -fpara monitorar os logs em tempo real enquanto tenta reproduzir o erro.
tail -f /var/log/nginx/error.log
O que procurar:
* connect() failed (111: Connection refused): Indica que o servidor upstream não está escutando no endereço/porta especificada ou um firewall está bloqueando a conexão.
* upstream timed out: O servidor upstream demorou muito para responder.
* upstream prematurely closed connection: O servidor upstream fechou a conexão antes de enviar uma resposta completa.
* no live upstreams while connecting to upstream: O Nginx não conseguiu encontrar nenhum servidor upstream configurado disponível.
2. Verifique o Status do Servidor Upstream
Depois de ter pistas nos logs de erro do Nginx, verifique o status do seu servidor de aplicação upstream.
-
Para PHP-FPM:
bash systemctl status phpX.X-fpm # Substitua X.X pela sua versão PHP, ex: php7.4-fpm sudo service phpX.X-fpm status -
Para Node.js/Python/Outras Aplicações Personalizadas:
Verifique se o processo está em execução.bash ps aux | grep node ps aux | grep gunicorn
Se estiver usando um gerenciador de processos como PM2 (Node.js) ou Supervisor (geral), verifique seu status.bash pm2 status sudo supervisorctl status
Se o serviço não estiver em execução, tente iniciá-lo e verifique seus próprios logs em busca de erros.
systemctl start phpX.X-fpm
# Ou
sudo service phpX.X-fpm start
3. Verifique a Conectividade de Rede com o Upstream
Garanta que o Nginx possa alcançar o servidor upstream na porta ou caminho do socket configurado.
-
Para conexões TCP/IP (ex:
127.0.0.1:8000):
Usetelnetounc(netcat) para testar a conectividade da porta a partir do servidor Nginx.bash telnet 127.0.0.1 8000 nc -vz 127.0.0.1 8000
Uma conexão bem-sucedida deve mostrarConnected to 127.0.0.1.ousucceeded!. Se travar ou mostrarConnection refused, o serviço upstream não está escutando ou um firewall o está bloqueando. -
Para sockets Unix (ex:
unix:/run/php/phpX.X-fpm.sock):
Verifique se o arquivo socket existe e tem as permissões corretas.bash ls -l /run/php/phpX.X-fpm.sock
O Nginx deve ter permissões de leitura/escrita para este arquivo socket. O usuário Nginx (ex:www-data) precisa fazer parte do grupo que possui o socket (ex:www-dataouphp-fpm).
Causas Comuns e Soluções
Com base em suas etapas de diagnóstico, aqui estão as causas mais frequentes de erros 502 e como resolvê-las.
1. Servidor Upstream Não Está Rodando ou Travou
Causa: A aplicação para a qual o Nginx está tentando fazer proxy (ex: PHP-FPM, Gunicorn, aplicação Node.js) não está em execução ou travou.
Solução: Inicie ou reinicie o serviço upstream.
# Exemplo para PHP-FPM
systemctl start phpX.X-fpm
# Se já estiver em execução e você suspeitar de um travamento, reinicie-o:
systemctl restart phpX.X-fpm
# Para aplicações personalizadas, use seus comandos específicos de iniciar/reiniciar
Dica: Certifique-se de que seus serviços upstream estejam configurados para iniciar automaticamente na inicialização do sistema. Para serviços systemd, use systemctl enable phpX.X-fpm.
2. Sobrecarga do Servidor Upstream / Esgotamento de Recursos
Causa: O servidor upstream está sobrecarregado, ficando sem memória, CPU ou atingindo limites de processos, fazendo com que pare de responder ou recuse novas conexões.
Sintomas: Os logs de erro do Nginx podem mostrar connection refused ou upstream timed out intermitentemente, especialmente sob carga. Ferramentas de monitoramento do sistema (top, htop, free -h) mostram alto uso de recursos.
Soluções:
-
Para PHP-FPM: Ajuste as configurações de pool do PHP-FPM em seu arquivo de configuração (ex:
/etc/php/X.X/fpm/pool.d/www.conf).pm.max_children: O número máximo de filhos que podem estar ativos ao mesmo tempo.pm.start_servers: O número de filhos criados na inicialização.pm.min_spare_servers,pm.max_spare_servers: Controlam quantos filhos ociosos são mantidos.
ini ; Exemplo para gerenciamento dinâmico de processos pm = dynamic pm.max_children = 50 pm.start_servers = 10 pm.min_spare_servers = 5 pm.max_spare_servers = 20
* Aumentememory_limitnophp.inise os scripts estiverem esgotando a memória.
* Para outras aplicações: Aumente o número de processos workers, threads ou aloque mais memória, se possível. Monitore as métricas específicas da sua aplicação.
* Timeouts do Nginx: Aumente as diretivasproxy_connect_timeout,proxy_send_timeouteproxy_read_timeoutdo Nginx na sua configuração do Nginx, mas entenda que isso apenas atrasa o erro se o backend estiver realmente com problemas.nginx http { ... proxy_connect_timeout 60s; proxy_send_timeout 60s; proxy_read_timeout 60s; ... }
3. Configuração Upstream Incorreta no Nginx
Causa: O Nginx está configurado para se conectar ao IP errado, porta ou caminho do socket Unix para o servidor upstream.
Sintomas: Os logs de erro do Nginx mostram connect() failed (111: Connection refused) imediatamente após uma requisição.
Solução: Revise cuidadosamente a configuração do seu bloco de servidor Nginx (/etc/nginx/sites-available/your_site.conf).
-
Para upstreams HTTP/HTTPS:
nginx location /app { proxy_pass http://127.0.0.1:8000; # Garanta que o IP e a porta estejam corretos proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } -
Para PHP-FPM via socket Unix:
nginx location ~ \.php$ { fastcgi_pass unix:/run/php/phpX.X-fpm.sock; # Verifique se este caminho corresponde exatamente à configuração do PHP-FPM fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; } -
Para PHP-FPM via TCP/IP:
nginx location ~ \.php$ { fastcgi_pass 127.0.0.1:9000; # Verifique IP e porta fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; }
Após fazer alterações, sempre teste sua configuração Nginx e recarregue/reinicie o Nginx:
nginx -t
systemctl reload nginx # Ou reinicie se -t indicar necessidade
4. Excedido o request_terminate_timeout do PHP-FPM
Causa: Um script PHP leva mais tempo para ser executado do que a configuração request_terminate_timeout no PHP-FPM. O Nginx espera pela resposta, mas o PHP-FPM encerra o script, fazendo com que o Nginx receba uma resposta incompleta.
Sintomas: Os logs de erro do Nginx podem mostrar upstream timed out ou script timed out. Os logs do PHP-FPM podem mostrar child XX exited on signal 9 (SIGKILL).
Solução:
* Aumentar request_terminate_timeout: Na configuração do seu pool PHP-FPM (www.conf), localize e ajuste esta diretiva. Definir como 0 desativa o timeout, mas geralmente não é recomendado, pois scripts de longa execução podem travar recursos.
```ini
request_terminate_timeout = 300 # Aumentar para 5 minutos (300 segundos)
```
-
Aumentar
fastcgi_read_timeoutno Nginx: Este timeout do Nginx deve ser igual ou superior arequest_terminate_timeout.nginx location ~ \.php$ { ... fastcgi_read_timeout 300s; # Deve ser >= request_terminate_timeout do PHP-FPM ... }
Aviso: Embora aumentar os timeouts possa resolver o erro 502, isso pode mascarar problemas de desempenho subjacentes. A melhor solução a longo prazo é otimizar o script PHP lento.
5. Problemas de Firewall
Causa: Um firewall (seja no servidor Nginx ou no servidor upstream, se forem separados) está bloqueando as conexões para a porta ou socket upstream.
Solução:
* Verificar o status do firewall:
```bash
sudo ufw status # Para UFW (Ubuntu/Debian)
sudo firewall-cmd --list-all # Para firewalld (CentOS/RHEL)
sudo iptables -L # Para iptables
```
-
Abrir as portas necessárias: Certifique-se de que a porta que o Nginx usa para se conectar ao upstream (ex: 9000 para PHP-FPM via TCP/IP) esteja aberta.
bash sudo ufw allow from 127.0.0.1 to any port 9000 # Permitir conexão do localhost na porta 9000 sudo firewall-cmd --permanent --add-port=9000/tcp # Para firewalld sudo firewall-cmd --reload
* Desligue temporariamente o firewall para fins de teste apenas em um ambiente controlado, depois reative-o e configure-o adequadamente.
6. Interferência do SELinux ou AppArmor
Causa: Melhorias de segurança como SELinux (no RHEL/CentOS) ou AppArmor (no Ubuntu/Debian) podem estar impedindo o Nginx de acessar o socket upstream ou fazer conexões de rede, mesmo que as permissões de arquivo e os firewalls estejam configurados corretamente.
Sintomas: Os logs podem mostrar mensagens como permission denied ou semelhantes, especialmente em /var/log/audit/audit.log (para SELinux).
Solução:
* Verificar audit.log:
```bash
sudo grep nginx /var/log/audit/audit.log
```
- Definir temporariamente o SELinux como permissivo:
sudo setenforce 0. Se o erro for resolvido, o SELinux é o culpado. Você precisará gerar e aplicar as políticas SELinux apropriadas (ex:audit2allow). Lembre-se de redefini-lo para enforcing (sudo setenforce 1). - Verificar o status do AppArmor:
sudo aa-status. Se o AppArmor estiver ativo, você pode precisar ajustar o perfil do Nginx.
7. Corpos de Requisição/Resposta Grandes (Proxy Buffering)
Causa: As configurações padrão de buffer de proxy do Nginx podem ser muito pequenas para corpos de requisição ou resposta muito grandes, levando ao fechamento prematuro da conexão.
Sintomas: Os logs de erro do Nginx podem mostrar upstream prematurely closed connection while reading response header from upstream ou upstream prematurely closed connection while reading response body from upstream.
Solução: Ajuste as diretivas de buffer de proxy do Nginx em seus blocos http, server ou location.
http {
...
proxy_buffer_size 128k; # Tamanho do buffer para a primeira parte da resposta
proxy_buffers 4 256k; # Número e tamanho dos buffers para o restante da resposta
proxy_busy_buffers_size 256k; # Tamanho máximo de buffers ocupados
proxy_temp_file_write_size 256k; # Tamanho para escrita em arquivos temporários se o buffering estourar
...
}
Nota: Essas configurações consomem mais memória. Ajuste-as com cautela com base nos recursos do seu servidor e no tamanho típico das respostas da sua aplicação.
Dicas Gerais de Solução de Problemas
- Revisar todos os logs relevantes: Além dos logs de erro do Nginx, verifique também os logs de acesso do Nginx, logs da aplicação upstream (PHP-FPM, Gunicorn, logs da aplicação Node.js) e logs do sistema (
/var/log/syslog,dmesg). - Reiniciar o Nginx: Após quaisquer alterações de configuração, sempre reinicie o Nginx para garantir que elas tenham efeito:
systemctl restart nginx. - Testar a Configuração do Nginx: Antes de reiniciar, valide a sintaxe da sua configuração Nginx:
nginx -t. - Isolar o Problema: Tente contornar o Nginx e acessar a aplicação upstream diretamente. Por exemplo, se sua aplicação Node.js estiver em
localhost:3000, usecurl http://localhost:3000a partir da linha de comando do servidor. Se isso também falhar, o problema é definitivamente com sua aplicação, não com o Nginx. - Verificar Espaço em Disco: Um disco cheio pode impedir que as aplicações gravem arquivos temporários ou logs, levando a falhas ou erros. Use
df -hpara verificar o uso do disco.
Conclusão
Os erros 502 Bad Gateway do Nginx são comuns, mas quase sempre apontam para um problema com a aplicação de backend à qual o Nginx está tentando se conectar, e não com o Nginx em si. Ao verificar sistematicamente os logs de erro do Nginx, verificar o status do servidor upstream, confirmar a conectividade de rede e, em seguida, resolver problemas comuns de configuração ou recursos, você pode diagnosticar e resolver esses problemas de forma eficaz.
Lembre-se de abordar a solução de problemas metodicamente, começando pelas verificações mais básicas e aprofundando progressivamente. Sempre teste sua configuração Nginx após fazer alterações e monitore a saúde da sua aplicação e do servidor para evitar ocorrências futuras. Com essas estratégias, você estará bem equipado para manter seus serviços funcionando sem problemas.