Proxy inverso con Traefik para servicios Docker: configuración práctica de producción
Cuando ejecutas varios servicios Docker en un solo host, la gestión de puertos se vuelve caótica muy rápido. Traefik resuelve ese problema actuando como un proxy inverso dinámico que descubre contenedores por etiquetas y aplica rutas de forma automática.
En esta guía verás una base realista para producción: TLS automático, enrutado limpio por dominio y una estrategia segura para el panel administrativo.
Resumen de arquitectura
Un diseño habitual incluye:
- Un punto de entrada externo en puertos 80/443
- Una red Docker interna compartida por Traefik y las apps
- Etiquetas por servicio para hostnames, middlewares y puertos internos
- Un resolvedor ACME para HTTPS automático
Traefik observa eventos de Docker y actualiza rutas sin recargas manuales, lo que reduce muchísimo el trabajo operativo cuando tus contenedores cambian con frecuencia.
1) Crea la red compartida
docker network create edge
Usa esta red tanto para Traefik como para todos los contenedores que quieras exponer.
2) Despliega Traefik con Docker Compose
Ejemplo de docker-compose.yml para Traefik:
services:
traefik:
image: traefik:v3.1
container_name: traefik
restart: unless-stopped
command:
- --providers.docker=true
- --providers.docker.exposedbydefault=false
- --entrypoints.web.address=:80
- --entrypoints.websecure.address=:443
- --certificatesresolvers.letsencrypt.acme.email=admin@example.com
- --certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json
- --certificatesresolvers.letsencrypt.acme.httpchallenge=true
- --certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web
- --api.dashboard=true
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./letsencrypt:/letsencrypt
networks:
- edge
networks:
edge:
external: true
Crea el archivo de ACME con permisos estrictos:
mkdir -p letsencrypt
touch letsencrypt/acme.json
chmod 600 letsencrypt/acme.json
3) Enruta una app usando etiquetas
Ejemplo de servicio de aplicación:
services:
app:
image: ghcr.io/example/myapp:latest
restart: unless-stopped
networks:
- edge
labels:
- traefik.enable=true
- traefik.http.routers.myapp.rule=Host(`app.example.com`)
- traefik.http.routers.myapp.entrypoints=websecure
- traefik.http.routers.myapp.tls.certresolver=letsencrypt
- traefik.http.services.myapp.loadbalancer.server.port=8080
El DNS de app.example.com debe apuntar a la IP pública de tu servidor.
4) Asegura endpoints operativos
No expongas el dashboard sin autenticación. Si lo necesitas, protégelo con middleware:
labels:
- traefik.http.middlewares.admin-auth.basicauth.users=admin:$$apr1$$...
- traefik.http.routers.traefik.rule=Host(`traefik.example.com`)
- traefik.http.routers.traefik.service=api@internal
- traefik.http.routers.traefik.entrypoints=websecure
- traefik.http.routers.traefik.tls.certresolver=letsencrypt
- traefik.http.routers.traefik.middlewares=admin-auth
5) Endurecimiento para producción
- Mantén
exposedByDefault=false - Deja el socket de Docker en solo lectura
- Limita puertos con firewall
- Aplica rate limiting en endpoints públicos
- Añade cabeceras seguras (HSTS, anti-sniff, etc.)
Ejemplo de middleware de cabeceras:
- traefik.http.middlewares.secure-headers.headers.stsSeconds=31536000
- traefik.http.middlewares.secure-headers.headers.browserXssFilter=true
- traefik.http.middlewares.secure-headers.headers.contentTypeNosniff=true
Asocia estos middlewares a cada router que publique aplicaciones sensibles.
Lista de verificación
docker ps
docker logs traefik --tail=100
curl -I https://app.example.com
Resultado esperado:
- Certificado válido emitido
- Respuesta
HTTP/2 200(o el estado esperado de la app) - Sin errores de certificado en navegador
Conclusión
Traefik es una opción excelente para entornos Docker donde los servicios cambian con frecuencia. Con enrutado por etiquetas y TLS automático reduces configuración manual y mejoras la consistencia operativa.
La mayor mejora de fiabilidad viene de tres prácticas simples: segmentación de red, dashboard protegido y políticas explícitas de middleware por aplicación.