Reverse proxy con Nginx y SSL para automatizaciones en producción
Muchos proyectos llegan a un punto incómodo:
- el servicio ya funciona
- el webhook ya responde
- la automatización ya corre
pero todo sigue expuesto de forma rudimentaria:
- puertos públicos
- sin HTTPS
- sin un dominio claro
- sin una capa de entrada ordenada
Ese es el momento donde un reverse proxy deja de ser “algo de infra” y pasa a ser parte de la base operativa.
Qué vas a construir
El patrón será este:
Internet
↓
Nginx
↓
HTTPS + dominio
↓
Servicios internos en 127.0.0.1
├── frontend
├── backend
└── automatizaciones / webhooks
La idea es que Nginx sea la única puerta pública.
Cuándo conviene este enfoque
Tiene sentido cuando:
- tienes más de un servicio interno
- quieres SSL real
- necesitas exponer webhooks o paneles con criterio
- no quieres dejar puertos abiertos sin control
Es casi obligatorio cuando un sistema pasa de prueba técnica a uso real.
Paso 1: Publica servicios solo localmente
En lugar de:
ports:
- "5100:80"
mejor:
ports:
- "127.0.0.1:5100:80"
Y para una API:
ports:
- "127.0.0.1:5200:8000"
Eso deja el servicio accesible desde el host, pero no públicamente desde cualquier IP.
Paso 2: Deja que Nginx haga de puerta de entrada
La responsabilidad del proxy será:
- recibir tráfico público
- resolver dominio
- terminar SSL
- enrutar cada ruta al servicio correcto
Ejemplo mental:
tudominio.com -> frontend
tudominio.com/api -> backend
tudominio.com/hooks -> automatizaciones
Paso 3: Configura el server block básico
Ejemplo mínimo de Nginx:
server {
listen 80;
server_name app.tudominio.com;
location / {
proxy_pass http://127.0.0.1:5100;
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;
}
}
Y para una API:
location /api/ {
proxy_pass http://127.0.0.1:5200/;
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;
}
Paso 4: Añade HTTPS
Si vas a exponer:
- paneles
- formularios
- webhooks
- credenciales
- tráfico interno sensible
entonces necesitas HTTPS real.
Con certificados válidos, la configuración general queda así:
server {
listen 443 ssl http2;
server_name app.tudominio.com;
ssl_certificate /ruta/fullchain.pem;
ssl_certificate_key /ruta/privkey.pem;
location / {
proxy_pass http://127.0.0.1:5100;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto https;
}
}
Y una redirección simple desde HTTP:
server {
listen 80;
server_name app.tudominio.com;
return 301 https://$host$request_uri;
}
Paso 5: Separa frontend, backend y webhooks con rutas claras
Una organización razonable:
/-> frontend/api/-> backend/webhooks/-> automatizaciones o n8n
Esa claridad ayuda mucho para:
- debug
- logs
- reglas de seguridad
- rate limiting por tipo de endpoint
Paso 6: Añade cabeceras y timeouts razonables
Además del proxy_pass, conviene definir:
- headers de forwarding
- timeout apropiado
- tamaño máximo de body si recibes archivos o payloads grandes
Ejemplo:
client_max_body_size 10m;
proxy_read_timeout 60s;
proxy_connect_timeout 10s;
No todos los servicios necesitan el mismo tratamiento. Un webhook lento no se comporta igual que una landing estática.
Paso 7: Piensa la seguridad por superficie
No todos los paths deberían tratarse igual.
Ejemplos:
/público/api/admin/restringido/webhooks/public/muy controlado/n8n/con auth adicional o acceso restringido
Un reverse proxy bien usado también te ayuda a segmentar exposición.
Paso 8: Registra logs útiles
Si un webhook falla o una automatización no responde, necesitas saber:
- qué llegó
- cuándo
- a qué upstream fue
- qué código devolvió
No hace falta empezar con observabilidad sofisticada, pero sí con logs legibles y consistentes.
Paso 9: Entiende el papel del Nginx del contenedor vs el del host
En este proyecto ya existe un nginx.conf para servir el frontend Astro dentro del contenedor.
Ese Nginx resuelve:
- archivos estáticos
- cache de assets
- fallback de rutas
Pero no reemplaza al reverse proxy del host.
Son capas distintas:
- Nginx del contenedor: sirve el sitio
- Nginx del VPS: expone dominios, SSL y routing público
Confundirlas suele complicar muchísimo el despliegue.
Errores comunes
1) Exponer cada servicio con un puerto público
Eso multiplica superficie y desordena la arquitectura.
2) No usar HTTPS
Funciona “hasta que deja de ser aceptable”.
3) Mezclar rutas sin criterio
Si frontend, API y webhooks comparten espacio sin convención, mantenerlo se vuelve confuso.
4) No forwardear headers importantes
Sin eso, muchos servicios no entienden correctamente host, IP o protocolo real.
5) No diferenciar el proxy del host del web server interno
Eso lleva a configuraciones duplicadas o contradictorias.
Cuándo esta base ya es suficiente
Para muchos proyectos pequeños y medianos, este patrón ya da una base muy digna:
- un único punto de entrada
- SSL centralizado
- puertos internos
- rutas claras
- servicios desacoplados
No necesitas complejidad extra para tener una estructura razonable.
Resumen
Un reverse proxy con Nginx y SSL te permite:
- exponer servicios con criterio
- centralizar HTTPS
- ocultar puertos internos
- enrutar frontend, API y automatizaciones
- mejorar seguridad y operación
No es un detalle cosmético de infraestructura.
Es una de las capas que separa un sistema “que responde” de uno que realmente está listo para usarse en producción.
Si necesitas ordenar la exposición pública de tus servicios, dejar webhooks y automatizaciones detrás de una base más seria o montar un esquema de deploy más mantenible, puedes escribirme desde Sobre Mí.