
Configuración de proxies inversos con Nginx para aplicaciones Node.js
El uso de Nginx como proxy inverso delante de aplicaciones Node.js es una práctica estándar para mejorar rendimiento, seguridad y escalabilidad. En esta guía técnica y práctica repasaremos la configuración básica y avanzada: SSL/TLS con Let’s Encrypt, soporte de WebSockets, balanceo de carga, optimizaciones de tiempo de respuesta y recomendaciones de seguridad.
Por qué usar Nginx delante de Node.js
Node.js es excelente manejando I/O asíncrono, pero delegar responsabilidades de transporte y cache a Nginx aporta beneficios claros:
- Terminación SSL eficiente y gestión de certificados.
- Soporte estable para conexiones estáticas y compresión (gzip).
- Balanceo de carga y manejo de sesiones para múltiples instancias Node.
- Protección frente a ataques de capa 7 mediante límites y cabeceras.
- Compatibilidad con WebSockets y proxys HTTP/2.
Arquitectura típica
Diagrama simplificado:
- Cliente <-> Nginx (SSL, HTTP/2, cache) <-> Node.js (pm2, systemd)
- Para alta disponibilidad: varios Nginx frente a varios backends Node
Configuración mínima: bloque server
Ejemplo de bloque Nginx para servir una app Node.js en el puerto 3000. Coloca este archivo en /etc/nginx/sites-available/tu_app y crea el enlace simbólico a sites-enabled.
upstream app_node {
server 127.0.0.1:3000;
# server 127.0.0.1:3001; # instancias adicionales para balanceo
}
server {
listen 80;
server_name ejemplo.com www.ejemplo.com;
location / {
proxy_pass http://app_node;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 90;
}
}
Notas sobre la configuración
- proxy_http_version 1.1 y cabeceras Upgrade/Connection son necesarias para WebSockets.
- proxy_read_timeout evita timeouts en peticiones largas (subidas, SSE, etc.).
- Usa upstream para facilitar el balanceo y la salud de instancias.
SSL/TLS: terminación con Let’s Encrypt
Es recomendable que Nginx maneje TLS. Let’s Encrypt permite certificados gratuitos y automatizados. El flujo típico:
- Instalar Certbot y obtener certificados.
- Configurar server blocks para redireccionar HTTP a HTTPS y usar certificados.
Ejemplo simplificado tras obtener certificados:
server {
listen 80;
server_name ejemplo.com www.ejemplo.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name ejemplo.com www.ejemplo.com;
ssl_certificate /etc/letsencrypt/live/ejemplo.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/ejemplo.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
location / {
proxy_pass http://app_node;
# cabeceras y ajustes como antes
}
}
Consulta la documentación oficial de Let’s Encrypt para automatizar renovaciones y opciones avanzadas.
Soporte para WebSockets y SSE
Las aplicaciones en tiempo real (Socket.io, ws) requieren proxys que mantengan la conexión. Los puntos clave ya vistos son:
- proxy_http_version 1.1
- proxy_set_header Upgrade $http_upgrade
- proxy_set_header Connection ‘upgrade’
- aumentar proxy_read_timeout para conexiones persistentes
Además, revisa compatibilidad de HTTP/2 si debes proxear WebSockets (HTTP/2 no soporta WebSockets nativamente; Nginx lo negocia correctamente si la conexión entre cliente y Nginx es HTTP/2 y la conexión Nginx-Node es HTTP/1.1).
Para conceptos de WebSockets consulta la referencia en MDN Web Docs.
Balanceo de carga y sticky sessions
Nginx ofrece varios métodos de balanceo: round-robin (por defecto), ip_hash o least_conn. Ejemplo con least_conn:
upstream app_node {
least_conn;
server 10.0.0.10:3000;
server 10.0.0.11:3000;
}
Si tu aplicación requiere afinidad de sesión, usa ip_hash o implementa sesiones compartidas en Redis para escalar sin sticky sessions.
Optimización de rendimiento y seguridad
- client_max_body_size 10M para controlar subidas de archivos.
- Gzip para respuestas estáticas: activar gzip con niveles moderados.
- Desactivar proxy_buffering para respuestas en tiempo real cuando sea necesario.
- Limitar conexiones por IP y peticiones por segundo para mitigar abusos.
- Configurar cabeceras HSTS, X-Frame-Options y Content-Security-Policy desde Nginx.
server {
# límites básicos
limit_conn_zone $binary_remote_addr zone=addr:10m;
limit_req_zone $binary_remote_addr zone=req:10m rate=10r/s;
location / {
limit_conn addr 10;
limit_req zone=req burst=20 nodelay;
proxy_pass http://app_node;
}
}
Despliegue y gestión de procesos Node.js
Para producción, ejecuta Node.js con un gestor de procesos como pm2 o systemd. pm2 facilita la administración y reinicio automático:
# instalar pm2
npm install -g pm2
# arrancar la app
pm2 start app.js --name 'app'
pm2 startup
pm2 save
Si usas systemd, crea un servicio que arranque tu aplicación y permita logs y reinicios configurables.
Monitoreo y logging
- Habilita access_log y error_log en Nginx con rotación (logrotate).
- Centraliza logs de Node.js con herramientas como ELK o Prometheus + Grafana.
- Monitorea métricas clave: latencia, conexiones activas, throughput y errores 5xx.
Buenas prácticas y checklist antes de producción
- Probar comportamiento con cargas concurrentes y WebSockets.
- Verificar renovación automática de certificados Let’s Encrypt.
- Auditar cabeceras de seguridad y políticas CSP/HSTS.
- Establecer límites de recursos y políticas de reintento en el cliente.
- Hacer pruebas de failover para balanceo y recuperación de nodos.
Enlaces de referencia
Documentación oficial de Nginx sobre proxy y módulos: NGINX.org – ngx_http_proxy_module. Para gestión de certificados usa Let’s Encrypt. Para conceptos de WebSockets y APIs web, revisa MDN Web Docs.
Conclusión
Configurar Nginx como proxy inverso para aplicaciones Node.js es una solución madura y flexible que mejora seguridad, rendimiento y escalabilidad. Empieza con una configuración simple—terminación TLS, proxy_pass y cabeceras para WebSockets—y añade balanceo, límites y monitoreo según crezcan tus necesidades. Aplicando las prácticas descritas ahorrarás tiempo en operación y obtendrás una plataforma más robusta para despliegues en producción.