Reverse Proxy con HTTPS Automático en 1 Docker Compose (Caddy + Tu App)
Aprende a montar un reverse proxy con HTTPS automático usando Caddy y Docker Compose en una VPS. Certificados Let’s Encrypt, subdominios y troubleshooting 502.
Contenido del tutorial ⌄
1. Reverse Proxy Mágico: Configurando Caddy
Si tienes una VPS y una app web (Next.js, Django, FastAPI), exponerla directamente a internet por el puerto 3000 o 8000 es un riesgo de seguridad y da una mala imagen (sin candado verde). La solución profesional es usar un Reverse Proxy.
Nuestra arquitectura será: Internet (HTTPS) → Caddy (80/443) → Tu App (Red interna). Usaremos Caddy porque gestiona los certificados TLS de Let's Encrypt y su renovación de forma 100% automática. Empecemos creando nuestra carpeta de trabajo y el archivo de configuración Caddyfile.
# 1. Crea la estructura de carpetas en tu VPS
# mkdir -p /opt/stack-caddy-app/caddy
# cd /opt/stack-caddy-app
# nano caddy/Caddyfile
{
# Recomendado: email para avisos ACME / Let's Encrypt en caso de problemas
email admin@tudominio.com
}
app.tudominio.com {
# Ajusta el nombre del servicio ('app') y el puerto interno
reverse_proxy app:3000
# Compresión para mejorar el rendimiento (opcional pero recomendado)
encode gzip zstd
# Cabeceras de seguridad base (opcional)
header {
X-Content-Type-Options "nosniff"
X-Frame-Options "DENY"
Referrer-Policy "no-referrer"
}
# HSTS (ACTÍVALO solo cuando ya estés 100% seguro de que el HTTPS funciona)
# header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
}
🔒 1) La Magia del ACME (HTTPS Automático)
A diferencia de Nginx, donde tienes que instalar un cronjob con Certbot, Caddy hace el desafío ACME de Let's Encrypt de forma nativa.
Con solo poner app.tudominio.com en el archivo, Caddy intercepta el tráfico HTTP en el puerto 80, valida que eres el dueño del dominio, descarga el certificado, lo instala y abre el puerto 443 (HTTPS). Todo en milisegundos y sin que escribas un solo script.
🚀 2) Múltiples Subdominios (Bonus)
Si tienes un backend y un frontend separados, Caddy lo resuelve con una elegancia brutal. Solo añades otro bloque al mismo archivo:
api.tudominio.com { reverse_proxy api:8000 }
app.tudominio.com { reverse_proxy app:3000 }
Caddy generará certificados independientes para cada subdominio y enrutará el tráfico al contenedor correcto dentro de la red de Docker.
2. El Orquestador: docker-compose.yml
Ahora necesitamos unir nuestro servidor Caddy con nuestra Aplicación. Para que el reverse_proxy app:3000 del paso anterior funcione, ambos servicios deben vivir en la misma red de Docker.
Aquí aplicaremos una regla de oro en ciberseguridad: Minimizar la superficie de ataque. Caddy será el único contenedor que hable con internet (exponiendo puertos). Tu aplicación quedará aislada y blindada dentro de la red interna de Docker.
# nano /opt/stack-caddy-app/docker-compose.yml
services:
caddy:
image: caddy:2-alpine
container_name: caddy
restart: unless-stopped
ports:
- "80:80" # HTTP (necesario para el desafío ACME)
- "443:443" # HTTPS
volumes:
- ./caddy/Caddyfile:/etc/caddy/Caddyfile:ro
- caddy_data:/data # Guarda los certificados aquí
- caddy_config:/config
networks:
- web
app:
# Opción A: construir desde Dockerfile local
build:
context: .
dockerfile: Dockerfile
# Opción B: usar una imagen ya publicada en un registry
# image: tuusuario/tuapp:latest
container_name: app
restart: unless-stopped
expose:
- "3000" # Solo expuesto a la red interna (¡NO usar ports!)
environment:
- NODE_ENV=production
networks:
- web
networks:
web:
volumes:
caddy_data:
caddy_config:
Comentarios y valoraciones
No hay comentarios aún. ¡Sé el primero en opinar!