Configura Nginx como Reverse Proxy y API Gateway
Como usar Nginx como reverse proxy para servicios backend, implementar balanceo de carga, terminacion SSL y rate limiting para API gateways de produccion
Nginx es un servidor web de alto rendimiento que destaca como reverse proxy y API gateway. Maneja terminacion SSL, balanceo de carga entre multiples backends, routing basado en paths y rate limiting — todo con minimo overhead de memoria y rendimiento predecible bajo alta concurrencia.
Cuando Usar Esto
- Necesitas exponer multiples servicios backend a traves de un unico punto de entrada
- La terminacion SSL/TLS debe ocurrir en el edge, no en codigo de aplicacion. Consulta Guía de Seguridad para lo que funciona para TLS.
- Quieres agregar rate limiting, cacheo o reescritura de peticiones sin modificar backends
Requisitos Previos
- Nginx 1.18+ instalado
- Servicios backend ejecutandose en puertos o hostnames conocidos
Solucion
1. Reverse Proxy Basico
# /etc/nginx/sites-available/api
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
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;
}
}
2. Routing Basado en Paths a Multiples Servicios
# /etc/nginx/sites-available/gateway
server {
listen 80;
server_name gateway.example.com;
# Servicio de usuarios
location /api/users/ {
proxy_pass http://user-service:8080/;
proxy_set_header Host $host;
}
# Servicio de ordenes
location /api/orders/ {
proxy_pass http://order-service:8081/;
proxy_set_header Host $host;
}
# Servicio de pagos
location /api/payments/ {
proxy_pass http://payment-service:8082/;
proxy_set_header Host $host;
}
# Assets estaticos desde CDN
location /assets/ {
proxy_pass https://cdn.example.com/;
proxy_cache_valid 200 1h;
}
}
3. Balanceo de Carga con Health Checks
# /etc/nginx/conf.d/upstreams.conf
upstream user_service {
least_conn;
server 10.0.1.10:8080 weight=5;
server 10.0.1.11:8080 weight=5;
server 10.0.1.12:8080 backup;
keepalive 32;
}
server {
location /api/users/ {
proxy_pass http://user_service/;
proxy_connect_timeout 5s;
proxy_read_timeout 30s;
}
}
4. Rate Limiting
# /etc/nginx/conf.d/rate-limit.conf
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;
limit_conn_zone $binary_remote_addr zone=addr:10m;
server {
location /api/ {
limit_req zone=api_limit burst=20 nodelay;
limit_conn addr 10;
limit_req_status 429;
proxy_pass http://backend/;
}
}
5. Terminacion SSL con Let’s Encrypt
# /etc/nginx/sites-available/api-ssl
server {
listen 80;
server_name api.example.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name api.example.com;
ssl_certificate /etc/letsencrypt/live/api.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384';
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://localhost:3000;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto https;
}
}
6. Cacheo de Respuestas
# /etc/nginx/conf.d/cache.conf
proxy_cache_path /var/cache/nginx/api
levels=1:2
keys_zone=api_cache:10m
max_size=1g
inactive=60m
use_temp_path=off;
server {
location /api/public/ {
proxy_cache api_cache;
proxy_cache_key "$scheme$request_method$host$request_uri";
proxy_cache_valid 200 10m;
proxy_cache_valid 404 1m;
proxy_cache_use_stale error timeout updating;
add_header X-Cache-Status $upstream_cache_status;
proxy_pass http://backend/;
}
# No cachear endpoints autenticados
location /api/private/ {
proxy_pass http://backend/;
proxy_set_header Cache-Control "no-store";
}
}
7. Proxy WebSocket
# /etc/nginx/sites-available/ws
server {
listen 80;
server_name ws.example.com;
location /socket.io/ {
proxy_pass http://localhost:3000;
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 86400s;
proxy_send_timeout 86400s;
}
}
8. Balanceo de Carga Ponderado con Fallback
upstream api_backend {
# Primario: 3 instancias con peso igual
server 10.0.1.10:8080 weight=3;
server 10.0.1.11:8080 weight=3;
server 10.0.1.12:8080 weight=3;
# Secundario: 2 instancias con peso menor para canary
server 10.0.1.20:8080 weight=1;
server 10.0.1.21:8080 weight=1;
# Backup: solo se usa cuando todos los primarios fallan
server 10.0.2.10:8080 backup;
keepalive 64;
keepalive_timeout 60s;
}
server {
location /api/ {
proxy_pass http://api_backend/;
proxy_next_upstream error timeout http_502 http_503 http_504;
proxy_next_upstream_tries 3;
proxy_next_upstream_timeout 10s;
}
}
9. Compresión con Brotli
# Requiere el modulo ngx_brotli
brotli on;
brotli_comp_level 6;
brotli_types text/plain text/css application/json application/javascript
text/xml application/xml application/xml+rss text/javascript;
server {
location /api/ {
proxy_pass http://backend/;
brotli on;
brotli_min_length 1024;
}
}
Variantes
| Feature | Nginx OSS | Nginx Plus | Traefik | Kong |
|---|---|---|---|---|
| Balanceo de carga | Round-robin, least_conn, ip_hash | + Health checks activos, slow start | Round-robin, ponderado | Round-robin, hashing consistente |
| Terminacion SSL | Si | Si + rotacion de certificados | Si (ACME) | Si |
| Rate limiting | Modulo limit_req | Si | Si (middleware) | Si (plugins) |
| Service discovery | Upstreams estaticos | DNS + etcd | Docker, K8s, Consul | K8s, Consul |
| Dashboard | No | Si (dashboard en vivo) | Si (web UI) | Si (admin API) |
| Auth por API key | Lua custom / auth_request | Si | Si (middleware) | Si (plugins) |
Como Funciona
- Reverse Proxy reenvia peticiones de clientes a servicios backend
- Path Routing mapea prefijos de URL a diferentes servicios upstream
- Load Balancing distribuye trafico entre instancias backend saludables
- Rate Limiting previene abuso usando algoritmos de token bucket
- SSL Termination desencripta trafico HTTPS en el edge para eficiencia del backend
Consideraciones de Produccion
- Habilita HTTP/2 en el frontend para conexiones multiplexadas
- Usa conexiones keepalive a backends para reducir overhead de TCP
- Implementa sticky sessions solo cuando sea necesario; prefiere diseno stateless
- Monitorea salud upstream con checks activos o deteccion pasiva de fallos. Consulta Logging y Auditoría de APIs para logging de health checks.
- Configura access logs con formato custom para capturar tiempo de respuesta upstream:
log_format upstream '$remote_addr - $request_time $upstream_response_time $status'; - Usa open file cache para assets estaticos:
open_file_cache max=1000 inactive=20s; open_file_cache_valid 30s; - Configura limites de body del cliente:
client_max_body_size 10m;para APIs que aceptan subida de archivos - Habilita gzip para respuestas de texto:
gzip on; gzip_types application/json text/css; - Setea server tokens off para ocultar la version de Nginx de los headers de respuesta
Errores Comunes
- No preservar headers
HostyX-Forwarded-*, rompiendo routing de backend - Usar balanceo
ip_hashsin considerar clientes NATed - Olvidar incrementar
worker_connectionspara despliegues de alto trafico - Setear
proxy_read_timeoutmuy bajo para endpoints de long-polling o streaming - No configurar
proxy_buffering offpara Server-Sent Events (SSE) — el buffering rompe el streaming en tiempo real - Usar
proxy_passcon slashes finales inconsistentes entre bloques location, causando duplicacion o truncamiento de paths - No setear
client_max_body_sizepara endpoints de subida de archivos, causando errores 413 - Olvidar recargar Nginx despues de cambios de config con
nginx -s reload
Preguntas frecuentes
Deberia usar Nginx o un API gateway como Kong o Traefik?
Nginx es suficiente para routing, SSL y rate limiting. Usa Kong o Traefik cuando necesites plugins, service discovery o capacidades nativas de Kubernetes.
Como manejo conexiones WebSocket a traves de Nginx?
Agrega proxy_set_header Upgrade $http_upgrade; y proxy_set_header Connection "upgrade"; al bloque de location.
Puede Nginx cachear respuestas de API?
Si. Usa proxy_cache con cache keys basados en URL y headers de autorizacion. Se cauteloso con endpoints autenticados.
Como ajusto los worker processes de Nginx para alto trafico?
Setea worker_processes auto; para coincidir con los cores de CPU. Incrementa worker_connections (ej. 10240) para despliegues de alto trafico. Usa worker_rlimit_nofile para coincidir. Habilita multi_accept on para trafico burst. Monitorea con nginx -T y ajusta basado en metricas de conexiones.
Cual es la diferencia entre proxy_pass con y sin slash final?
Con slash final (proxy_pass http://backend/;), Nginx elimina el prefijo de location coincidido antes de reenviar. Sin el (proxy_pass http://backend;), el URI completo se reenvia. Esto es una fuente comun de bugs de routing — prueba cuidadosamente.
Como implemento despliegues blue-green con Nginx?
Usa dos bloques upstream (blue y green) y cambia el target de proxy_pass. O usa balanceo ponderado para desplazar trafico gradualmente: empieza con weight=10 para blue y weight=0 para green, luego incrementa green y decrementa blue. Usa proxy_next_upstream para manejar fallos durante el switch.
Como bloqueo IPs o user agents especificos?
Usa directivas deny y allow para bloqueo de IPs. Para user agents, usa if con $http_user_agent o bloqueo basado en map. Ejemplo: deny 192.168.1.100; dentro de un bloque location. Para bloqueo a gran escala, usa un map con un archivo de lista de IPs y includealo.
Recursos Relacionados
Habilita compresión Brotli en Nginx para assets estáticos
Configura compresión Brotli en Nginx para reducir assets de JavaScript, CSS y HTML con mejores ratios que Gzip y cargar más rápido.
RecipeProvisionar una VPC de AWS con Terraform
Cómo usar Terraform para provisionar una VPC de AWS lista para producción con subredes públicas y privadas, NAT gateways y security groups
GuideDocker Compose: Desarrollo Local Multi-Servicio
Domina Docker Compose para desarrollo local: entornos multi-servicio, redes, volúmenes, profiles, overrides, hot reload, depuración, stacks de test y los scripts que lo hacen cómodo de usar.
RecipeLoad Balancing con HAProxy y Health Checks
Configura HAProxy como load balancer de alto rendimiento con health checks activos, sticky sessions y SSL termination para distribucion resiliente de servicios