Nginx: 502 Bad Gateway y errores de configuración más comunes
Cómo resolver los errores más comunes de Nginx: 502 Bad Gateway, puerto en uso, permisos y configuración incorrecta de proxy_pass.
¿Por qué ocurre?
Los errores más frecuentes de Nginx son: - **502 Bad Gateway**: Nginx no puede conectar con el upstream (tu app Node.js, PHP, etc.) - **bind() failed: Address already in use**: el puerto 80 o 443 ya está ocupado por otro proceso - **Permission denied**: Nginx no puede leer los archivos estáticos o el socket - **No such file or directory**: ruta incorrecta en root, alias o proxy_pass - **upstream timed out**: la app tarda demasiado en responder
Solución paso a paso
1. Diagnosticar con los logs de Nginx
# Log de errores (el más útil)
sudo tail -50 /var/log/nginx/error.log# Log de acceso
sudo tail -50 /var/log/nginx/access.log
# Estado del servicio
sudo systemctl status nginx
# Verificar sintaxis de la configuración
sudo nginx -t
2. 502 Bad Gateway — app no responde
# 1. ¿Está corriendo tu app?
systemctl status mi-app # si es un servicio
pm2 status # si usas PM2 con Node.js
ps aux | grep node# 2. ¿Escucha en el puerto correcto?
ss -tlnp | grep 3000 # ver qué hay en el puerto 3000
# 3. Verificar proxy_pass en nginx.conf
server {
listen 80;
server_name mi-dominio.com; location / {
proxy_pass http://localhost:3000; # ← puerto debe coincidir con tu app
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_read_timeout 60s; # ← aumentar si la app tarda
}
}
3. Puerto 80 ya en uso
# Ver qué proceso usa el puerto 80
sudo lsof -i :80
sudo ss -tlnp | grep :80# Matar el proceso (con cuidado)
sudo kill -9
# Si es Apache compitiendo con Nginx
sudo systemctl stop apache2
sudo systemctl disable apache2
sudo systemctl start nginx
4. Permisos en archivos estáticos
# Nginx corre como www-data (Ubuntu) o nginx (CentOS)
# Los archivos deben ser legibles por ese usuario# Ver usuario de Nginx
ps aux | grep nginx | head -1
# Dar permisos correctos
sudo chown -R www-data:www-data /var/www/mi-sitio
sudo chmod -R 755 /var/www/mi-sitio
# Verificar que Nginx puede leer el directorio
sudo -u www-data ls /var/www/mi-sitio
5. Configuración completa para sitio estático + proxy
server {
listen 80;
server_name mi-dominio.com www.mi-dominio.com; # Archivos estáticos (React/Vue build)
root /var/www/mi-sitio/dist;
index index.html;
# SPA: redirigir todas las rutas al index.html
location / {
try_files $uri $uri/ /index.html;
}
# API proxy
location /api {
proxy_pass http://localhost:3001;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
# Archivos estáticos con caché
location ~* \.(js|css|png|jpg|gif|ico|svg|woff2)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
}
6. Recargar configuración sin downtime
# Verificar sintaxis primero
sudo nginx -t# Recargar sin reiniciar (cero downtime)
sudo nginx -s reload
# O con systemctl
sudo systemctl reload nginx
Cómo evitarlo en el futuro
- Ejecuta `sudo nginx -t` siempre antes de recargar para verificar la sintaxis - Usa `sudo nginx -s reload` en lugar de `restart` para zero-downtime en producción - Configura `proxy_read_timeout` y `proxy_connect_timeout` según el tiempo de respuesta de tu app - Centraliza los logs con herramientas como Loki + Grafana o ELK Stack en producción
¿Quieres que una IA te ayude? Genera el prompt perfecto para tu error:
Generador de Prompts