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.