Como Diagnosticar e Resolver Erros 502 Bad Gateway no Nginx
Corrija erros 502 do Nginx verificando logs de erro, saúde do upstream, permissões de socket, configurações de proxy, timeouts e firewalls.
Como Diagnosticar e Resolver Erros 502 Bad Gateway no Nginx
O Nginx é um servidor web e proxy reverso poderoso e popular, frequentemente usado para servir conteúdo estático, balancear 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 normalmente responde com um erro "502 Bad Gateway".
Comece pelo log de erros do Nginx, depois verifique se o processo upstream está em execução, acessível e autorizado a responder.
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 não recebeu resposta, recebeu 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.
O erro 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 pelos 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 frequentemente contêm detalhes específicos sobre por que o Nginx não conseguiu se comunicar com o servidor upstream.
- Localização: Normalmente 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á ouvindo no endereço/porta especificados 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 disponível configurado.
2. Verifique o Status do Servidor Upstream
Assim que tiver pistas dos logs de erro do Nginx, verifique o status do seu servidor de aplicação upstream.
Para PHP-FPM:
sudo systemctl status php8.2-fpmPara Node.js/Python/Outras Aplicações Customizadas: Verifique se o processo está em execução.
ps aux | grep node ps aux | grep gunicornSe estiver usando um gerenciador de processos como PM2 (Node.js) ou Supervisor (geral), verifique seu status.
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.
sudo systemctl start php8.2-fpm
3. Verifique a Conectividade de Rede com o Upstream
Certifique-se de que o Nginx pode alcançar o servidor upstream na porta ou caminho de 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.telnet 127.0.0.1 8000 nc -vz 127.0.0.1 8000Uma conexão bem-sucedida deve mostrar
Connected to 127.0.0.1.ousucceeded!. Se travar ou mostrarConnection refused, o serviço upstream não está ouvindo ou um firewall está bloqueando.Para sockets Unix (ex.:
unix:/run/php/phpX.X-fpm.sock): Verifique se o arquivo de socket existe e tem as permissões corretas.ls -l /run/php/phpX.X-fpm.sockO Nginx deve ter permissões de leitura/escrita neste arquivo de socket. O usuário do Nginx (ex.:
www-data) precisa fazer parte do grupo que possui o socket (ex.:www-dataouphp-fpm).
Causas Comuns e Soluções
Com base nas 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á em Execução ou Falhou
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 falhou.
Solução: Inicie ou reinicie o serviço upstream.
# Exemplo para PHP-FPM
sudo systemctl start php8.2-fpm
# Se já estiver em execução e você suspeitar de uma falha, reinicie:
sudo systemctl restart php8.2-fpm
# Para aplicações customizadas, use seus comandos específicos de início/reinício
Dica: Certifique-se de que seus serviços upstream estão configurados para iniciar automaticamente na inicialização do sistema. Para serviços systemd, use systemctl enable phpX.X-fpm.
2. Sobrecarga do Servidor Upstream / Exaustão de Recursos
Causa: O servidor upstream está sobrecarregado, ficando sem memória, CPU ou atingindo limites de processo, 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 do pool do PHP-FPM no 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: Controla quantos filhos ociosos são mantidos.
; 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- Aumente
memory_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 diretivas
proxy_connect_timeout,proxy_send_timeouteproxy_read_timeoutna configuração do Nginx, mas entenda que isso apenas atrasa o erro se o backend estiver realmente com dificuldades.http { ... proxy_connect_timeout 60s; proxy_send_timeout 60s; proxy_read_timeout 60s; ... }
3. Configuração Incorreta do Upstream no Nginx
Causa: O Nginx está configurado para conectar ao endereço IP, porta ou caminho de socket Unix errado 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 bloco de servidor do Nginx (/etc/nginx/sites-available/your_site.conf).
Para upstreams HTTP/HTTPS:
location /app { proxy_pass http://127.0.0.1:8000; # Certifique-se de que o IP e a porta estão 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:
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:
location ~ \.php$ { fastcgi_pass 127.0.0.1:9000; # Verifique o IP e a 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 do Nginx e recarregue/reinicie o Nginx:
nginx -t
systemctl reload nginx # Ou reinicie se -t indicar necessidade
4. request_terminate_timeout do PHP-FPM Excedido
Causa: Um script PHP leva mais tempo para executar do que a configuração request_terminate_timeout no PHP-FPM. O Nginx aguarda a resposta, mas o PHP-FPM termina 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:
Aumente
request_terminate_timeout: Na configuração do pool do PHP-FPM (www.conf), encontre e ajuste esta diretiva. Definir como0desativa o timeout, mas isso geralmente não é recomendado, pois scripts de longa duração podem travar recursos.request_terminate_timeout = 300 # Aumente para 5 minutos (300 segundos)Aumente
fastcgi_read_timeoutno Nginx: Este timeout do Nginx deve ser igual ou maior querequest_terminate_timeout.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 (no servidor Nginx ou no servidor upstream, se forem separados) está bloqueando conexões para a porta ou socket upstream.
Solução:
Verifique o status do firewall:
sudo ufw status # Para UFW (Ubuntu/Debian) sudo firewall-cmd --list-all # Para firewalld (CentOS/RHEL) sudo iptables -L # Para iptablesAbra as portas necessárias: Certifique-se de que a porta que o Nginx usa para conectar ao upstream (ex.: 9000 para PHP-FPM via TCP/IP) está aberta.
sudo ufw allow from 127.0.0.1 to any port 9000 # Permite que localhost se conecte à porta 9000 sudo firewall-cmd --permanent --add-port=9000/tcp # Para firewalld sudo firewall-cmd --reloadDesative temporariamente o firewall para fins de teste apenas em um ambiente controlado, depois reative e configure-o corretamente.
6. Interferência do SELinux ou AppArmor
Causa: Aprimoramentos 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 firewalls estejam configurados corretamente.
Sintomas: Os logs podem mostrar permission denied ou mensagens semelhantes, especialmente em /var/log/audit/audit.log (para SELinux).
Solução:
Verifique
audit.log:sudo grep nginx /var/log/audit/audit.logDefina temporariamente o SELinux para modo permissivo:
sudo setenforce 0. Se o erro for resolvido, o SELinux é o culpado. Você precisará gerar e aplicar políticas SELinux apropriadas (ex.:audit2allow). Lembre-se de definir de volta para enforcing (sudo setenforce 1).Verifique o status do AppArmor:
sudo aa-status. Se o AppArmor estiver ativo, pode ser necessário ajustar o perfil do Nginx.
7. Corpos de Requisição/Resposta Grandes (Buffer de Proxy)
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 no bloco 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 resto da resposta
proxy_busy_buffers_size 256k; # Tamanho máximo dos buffers ocupados
proxy_temp_file_write_size 256k; # Tamanho para escrever em arquivos temporários se o buffer transbordar
...
}
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
- Revise 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). - Reinicie o Nginx: Após qualquer alteração na configuração, sempre reinicie o Nginx para garantir que elas entrem em vigor:
systemctl restart nginx. - Teste a Configuração do Nginx: Antes de reiniciar, valide a sintaxe da configuração do Nginx:
nginx -t. - Isole o Problema: Tente ignorar 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. - Verifique o Espaço em Disco: Um disco cheio pode impedir que as aplicações escrevam arquivos temporários ou logs, levando a falhas ou travamentos. Use
df -hpara verificar o uso do disco.
Conclusão
Comece com /var/log/nginx/error.log, depois verifique se o upstream está em execução e acessível a partir do host Nginx. Depois de saber se a falha é conexão recusada, timeout, permissão negada ou fechamento prematuro, a correção geralmente está no serviço upstream, permissões de socket, configurações de timeout ou regra de firewall.