Si gestionas múltiples aplicaciones con Docker Compose, sabes el dolor de mantener la configuración de Nginx sincronizada con tus contenedores. Cada vez que agregas un servicio, tienes que editar el archivo de Nginx, recargar la configuración y generar el certificado SSL. Traefik elimina ese trabajo: detecta tus contenedores automáticamente, crea las rutas y obtiene los certificados SSL — todo sin que toques un archivo de configuración.
Arquitectura
┌──────────────────────────────────────────────────┐
│ Internet │
│ :80 (HTTP) → :443 (HTTPS) │
└────────────────────┬─────────────────────────────┘
│
┌────────────────────▼─────────────────────────────┐
│ Traefik (contenedor) │
│ - Descubrimiento automático via Docker API │
│ - SSL automático con Let's Encrypt │
│ - Dashboard de monitoreo │
└───┬────────────────┬──────────────────┬──────────┘
│ │ │
┌───▼───┐ ┌────▼────┐ ┌────▼────┐
│ ERP │ │ API │ │ Grafana │
│:8069 │ │ :8000 │ │ :3000 │
│erp. │ │api. │ │monitor. │
│empresa│ │empresa │ │empresa │
│.com │ │.com │ │.com │
└───────┘ └─────────┘ └─────────┘
Traefik se conecta a la API de Docker, descubre los contenedores con labels específicas y automáticamente configura las rutas, middlewares y certificados.
Requisitos previos
Un servidor con Docker y Docker Compose instalados, un dominio que apunte al servidor (registro DNS tipo A) y los puertos 80 y 443 abiertos en tu firewall UFW.
Paso 1: Estructura del proyecto
traefik/
├── docker-compose.yml
├── .env
└── data/
├── traefik.yml # Configuración estática de Traefik
└── acme.json # Certificados SSL (se genera solo)
mkdir -p traefik/data
cd traefik
# Crear archivo de certificados con permisos correctos
touch data/acme.json
chmod 600 data/acme.json
Paso 2: Configuración estática de Traefik
cat > data/traefik.yml <<'EOF'
# --- Entrypoints ---
entryPoints:
web:
address: ":80"
http:
redirections:
entryPoint:
to: websecure
scheme: https
websecure:
address: ":443"
# --- Proveedor Docker ---
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false # Solo exponer contenedores con labels explícitas
network: proxy # Red que comparten Traefik y los servicios
# --- Let's Encrypt ---
certificatesResolvers:
letsencrypt:
acme:
email: admin@tuempresa.com
storage: /data/acme.json
httpChallenge:
entryPoint: web
# --- Dashboard ---
api:
dashboard: true
insecure: false # Solo accesible via router con autenticación
# --- Logs ---
log:
level: INFO
accessLog:
filePath: "/var/log/traefik/access.log"
bufferingSize: 100
EOF
Paso 3: Docker Compose con Traefik
# docker-compose.yml
services:
traefik:
image: traefik:v3.2
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./data/traefik.yml:/etc/traefik/traefik.yml:ro
- ./data/acme.json:/data/acme.json
- traefik_logs:/var/log/traefik
networks:
- proxy
labels:
# Dashboard de Traefik
- "traefik.enable=true"
- "traefik.http.routers.dashboard.rule=Host(`traefik.tuempresa.com`)"
- "traefik.http.routers.dashboard.entrypoints=websecure"
- "traefik.http.routers.dashboard.tls.certresolver=letsencrypt"
- "traefik.http.routers.dashboard.service=api@internal"
# Autenticación básica para el dashboard
# Genera con: echo $(htpasswd -nB admin) | sed -e 's/\$/\$\$/g'
- "traefik.http.routers.dashboard.middlewares=dashboard-auth"
- "traefik.http.middlewares.dashboard-auth.basicauth.users=${DASHBOARD_AUTH}"
networks:
proxy:
name: proxy
external: true
volumes:
traefik_logs:
Crea la red externa que compartirán Traefik y todos tus servicios:
docker network create proxy
Crea el archivo .env:
# .env
# Genera con: echo $(htpasswd -nB admin) | sed -e 's/\$/\$\$/g'
DASHBOARD_AUTH=admin:$$2y$$05$$abc123...tu-hash-aqui
Genera el hash de contraseña para el dashboard:
sudo apt install apache2-utils -y
echo $(htpasswd -nB admin) | sed -e 's/\$/\$\$/g'
Levanta Traefik:
docker compose up -d
Verifica que funciona accediendo a https://traefik.tuempresa.com — deberías ver el dashboard con autenticación.
Paso 4: Agregar tu primera aplicación
Ahora la magia. Crea un servicio que Traefik descubra automáticamente. En otro directorio, crea un docker-compose.yml para tu aplicación:
# ~/apps/mi-app/docker-compose.yml
services:
app:
image: nginx:alpine
restart: unless-stopped
networks:
- proxy
labels:
- "traefik.enable=true"
- "traefik.http.routers.mi-app.rule=Host(`app.tuempresa.com`)"
- "traefik.http.routers.mi-app.entrypoints=websecure"
- "traefik.http.routers.mi-app.tls.certresolver=letsencrypt"
- "traefik.http.services.mi-app.loadbalancer.server.port=80"
networks:
proxy:
external: true
cd ~/apps/mi-app
docker compose up -d
En segundos, Traefik detecta el nuevo contenedor, crea la ruta app.tuempresa.com, obtiene el certificado SSL de Let's Encrypt y empieza a enrutar tráfico. Sin editar ningún archivo de Traefik, sin recargar nada.
Así de simple
Cada nueva aplicación es un docker compose up -d con las labels correctas. Traefik se encarga del resto — ruta, SSL, redirección HTTP→HTTPS. Cuando haces docker compose down, Traefik elimina la ruta automáticamente.
Paso 5: Ejemplo con aplicación real — API + PostgreSQL
Un stack más realista con tu API FastAPI y PostgreSQL:
# ~/apps/api/docker-compose.yml
services:
api:
build: .
restart: unless-stopped
environment:
DATABASE_URL: postgresql+asyncpg://app:${DB_PASSWORD}@db:5432/miapi
SECRET_KEY: ${SECRET_KEY}
depends_on:
db:
condition: service_healthy
networks:
- proxy
- backend
labels:
- "traefik.enable=true"
- "traefik.http.routers.api.rule=Host(`api.tuempresa.com`)"
- "traefik.http.routers.api.entrypoints=websecure"
- "traefik.http.routers.api.tls.certresolver=letsencrypt"
- "traefik.http.services.api.loadbalancer.server.port=8000"
# Rate limiting
- "traefik.http.routers.api.middlewares=api-ratelimit"
- "traefik.http.middlewares.api-ratelimit.ratelimit.average=100"
- "traefik.http.middlewares.api-ratelimit.ratelimit.burst=50"
db:
image: postgres:16-alpine
restart: unless-stopped
environment:
POSTGRES_DB: miapi
POSTGRES_USER: app
POSTGRES_PASSWORD: ${DB_PASSWORD}
volumes:
- pg_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U app -d miapi"]
interval: 10s
timeout: 5s
retries: 5
networks:
- backend
networks:
proxy:
external: true
backend:
volumes:
pg_data:
Nota las dos redes: proxy (conecta al API con Traefik) y backend (conecta al API con PostgreSQL). La base de datos no está en la red proxy — no es accesible desde internet, solo desde el contenedor de la API.
Paso 6: Middlewares útiles
Traefik soporta middlewares que aplicas con labels. Los más útiles:
Headers de seguridad
labels:
- "traefik.http.middlewares.security-headers.headers.stsSeconds=31536000"
- "traefik.http.middlewares.security-headers.headers.stsIncludeSubdomains=true"
- "traefik.http.middlewares.security-headers.headers.contentTypeNosniff=true"
- "traefik.http.middlewares.security-headers.headers.frameDeny=true"
- "traefik.http.middlewares.security-headers.headers.browserXssFilter=true"
- "traefik.http.routers.mi-app.middlewares=security-headers"
Compresión gzip
labels:
- "traefik.http.middlewares.gzip.compress=true"
- "traefik.http.routers.mi-app.middlewares=gzip"
IP whitelist (restringir acceso por IP)
labels:
- "traefik.http.middlewares.internal-only.ipallowlist.sourcerange=10.0.1.0/24,192.168.1.0/24"
- "traefik.http.routers.admin.middlewares=internal-only"
Combinar múltiples middlewares
labels:
- "traefik.http.routers.mi-app.middlewares=security-headers,gzip,api-ratelimit"
Paso 7: Monitorear Traefik con Prometheus
Traefik expone métricas para Prometheus. Agrega a tu traefik.yml:
metrics:
prometheus:
entryPoint: metrics
addServicesLabels: true
addEntryPointsLabels: true
entryPoints:
metrics:
address: ":8082"
Y la label para el contenedor de Traefik:
labels:
- "traefik.http.services.traefik-metrics.loadbalancer.server.port=8082"
Dashboard recomendado para Grafana: ID 17346 (Traefik Official).
Checklist de producción
Antes de exponer Traefik a internet, verifica:
- ✅
exposedByDefault: false— solo contenedores con labels se exponen - ✅ Docker socket montado como
:ro(read-only) - ✅
acme.jsoncon permisos600 - ✅ Dashboard protegido con autenticación
- ✅ Headers de seguridad aplicados
- ✅ Rate limiting en APIs públicas
- ✅ Logs de acceso habilitados
- ✅ Base de datos y servicios internos en red separada de
proxy
Siguientes pasos
Con Traefik configurado, puedes expandir:
- Canary deployments — enviar un porcentaje de tráfico a una nueva versión antes de cortar completamente
- Circuit breaker — detener tráfico a un servicio que está fallando para que se recupere
- Kubernetes — Traefik funciona como Ingress Controller nativo para clusters K8s
- Traefik + Authelia — single sign-on (SSO) para proteger múltiples aplicaciones con una sola autenticación
- Infraestructura Docker profesional — diseño de arquitectura, seguridad y monitoreo
Contenedores en producción
¿Necesitas una infraestructura Docker profesional?
Diseñamos la arquitectura de contenedores con Traefik, Docker Compose, monitoreo y seguridad para tu operación.



