Traefik: el proxy inverso dinámico que se configura solo
A la hora de exponer aplicaciones en un servidor, Nginx es el nombre clásico. Pero Traefik ha cambiado las reglas del juego: es un proxy inverso y equilibrador de carga dinámico que no necesita que edites configuraciones a mano cada vez que levantes un servicio. Descubre tus aplicaciones automáticamente, genera certificados SSL por ti y soporta HTTP/2 y TLS de forma nativa.
En resumen: Traefik se coloca entre el cliente e internet y tus aplicaciones, enrutando cada petición al servicio correcto según el dominio o la ruta. Su secreto son los proveedores: en lugar de configurar a mano cada backend, escucha eventos de Docker, Kubernetes o archivos locales y se configura solo. Incluye SSL automático con Let’s Encrypt, hot reload y una configuración en YAML muy legible.
- Instala Traefik como binario + servicio systemd en tu servidor Linux
- Expón aplicaciones Node.js por dominio o ruta sin tocar Nginx
- Gestiona certificados HTTPS con Let’s Encrypt de forma automática
- Descubre contenedores Docker automáticamente mediante sus labels
¿Por qué necesitas un proxy inverso?
Sin un proxy, el cliente debe conocer la ubicación exacta (IP y puerto) de cada instancia de tu aplicación. Si tienes una app Node.js escuchando en el puerto 3000, cualquiera que quiera usarla tendría que conectarse a IP:3000:
- Limitación: el cliente asume la carga de gestionar la conexión con el backend.
- Inseguridad: no existe una capa centralizada para gestionar certificados SSL ni políticas de tráfico.
Al insertar Traefik entre el cliente y las aplicaciones, se centraliza la comunicación:
- El cliente envía todas las solicitudes a un único punto de entrada en Traefik.
- Traefik aplica un algoritmo de equilibrio de carga (como Round Robin).
- La solicitud se reenvía a una de las instancias disponibles del backend.
Un cliente solo puede acceder a un puerto si: ese puerto está abierto en el firewall, está escuchando en una interfaz accesible (
0.0.0.0) y está publicado hacia internet (NAT, router, etc.).
La diferencia entre 0.0.0.0 y 127.0.0.1
Cuando levantas una aplicación Node.js, estas dos líneas tienen consecuencias muy distintas:
app.listen(3000, '0.0.0.0'); # Acepta conexiones desde cualquier interfaz
app.listen(3000, '127.0.0.1'); # Solo el propio servidor puede conectarse
0.0.0.0: cualquier PC de la red puede entrar.127.0.0.1: solo el propio servidor puede conectarse. Otro PC de la red no puede entrar, pero el proxy (Traefik/Nginx) sí, porque está en el mismo servidor.
E incluso con 0.0.0.0, el firewall puede bloquear el acceso externo:
sudo ufw deny 3000
Arquitectura de Traefik: el flujo de una petición
La arquitectura de Traefik se divide en piezas modulares. Una petición sigue siempre este orden:
- Petición entrante: llega a través de un EntryPoint (puerto).
- Filtrado: el Router analiza la petición mediante una Regla. Si coincide, toma el control.
- Procesamiento (opcional): el Middleware aplica modificaciones.
- Entrega: el Service recibe la petición y la envía a uno de los servidores backend configurados.
A. EntryPoints (puertos de entrada)
Son los puertos de red que escuchan las solicitudes entrantes. Los ejemplos típicos son el puerto 80 (HTTP) y el 443 (HTTPS). Representan la puerta de acceso pública a tu servidor.
B. Routers (enrutadores)
Analizan cada petición basándose en reglas (nombre del host, path, encabezados) para decidir a qué servicio enviarla. Son el puente entre el EntryPoint y el Service. Al ser configuración dinámica, puedes cambiar el destino del tráfico sin afectar al puerto de entrada.
C. Middlewares (capa intermedia)
Se sitúan entre el Router y el Service para transformar la petición antes de que llegue al backend: redirección de HTTP a HTTPS, autenticación básica, compresión, manipulación de cabeceras o rate limiting.
D. Services (servicios)
Definen dónde residen las aplicaciones de backend: la lista de servidores reales (IPs y puertos) donde se ejecuta la app, con su equilibrado de carga y comprobaciones de salud.
El modelo de configuración dual
Traefik separa su configuración en dos categorías:
- Configuración estática: los elementos que no cambian a menudo (entrypoints, conexiones con los proveedores). Si se modifica, hay que reiniciar el servicio.
- Configuración dinámica: la lógica de negocio (routers, services, middlewares). Traefik la monitoriza y la aplica en caliente, sin interrumpir conexiones activas.
Instalación de Traefik en Linux (binario + systemd)
La forma más limpia y estándar es instalar Traefik como binario + servicio systemd. Así obtienes control total, logs en journald, reinicios automáticos y cero dependencia de Docker.
1. Descargar el binario
Ve al repositorio oficial y descarga la versión que quieras desde los releases de Traefik. Por ejemplo, traefik_v3.6.15_linux_amd64.tar.gz. Al descomprimir verás un único binario, al que le das permisos de ejecución:
chmod +x traefik
Verifica con ./traefik version. Lo movemos a un directorio estándar para que el sistema pueda acceder a él globalmente:
sudo mv traefik /usr/local/bin/traefik
2. Crear la configuración estática
Creamos la carpeta de configuración y el archivo principal (la configuración estática):
sudo mkdir -p /etc/traefik/dynamic
sudo touch /etc/traefik/traefik.yml
Con esta configuración base:
entryPoints:
web:
address: ":80"
providers:
file:
directory: "/etc/traefik/dynamic"
watch: true
api:
dashboard: true
Aquí defines el entrypoint web (escucha en el puerto 80) y el file provider, que lee todos los .yml de /etc/traefik/dynamic. Con watch: true, editar un archivo recarga la configuración automáticamente, sin reiniciar.
3. Registrar Traefik como servicio systemd
Creamos el unit file:
sudo nano /etc/systemd/system/traefik.service
[Unit]
Description=Traefik Reverse Proxy
After=network.target
[Service]
ExecStart=/usr/local/bin/traefik --configFile=/etc/traefik/traefik.yml
Restart=always
RestartSec=3
[Install]
WantedBy=multi-user.target
Recargamos systemd y gestionamos el servicio:
sudo systemctl daemon-reload
sudo systemctl enable traefik
sudo systemctl start traefik
systemctl status traefik
journalctl -u traefik -f
Nota: si ejecutas el binario directamente con un usuario normal, verás el error
listen tcp :80: bind: permission denied. En Linux, los puertos por debajo del 1024 están protegidos y solo root puede abrirlos. El servicio systemd lo resuelve al ejecutarse con privilegios.
Para actualizar basta con sustituir el binario; para desinstalar, paras y deshabilitas el servicio y borras los archivos.
Exponer una aplicación Node.js con enrutamiento por Host
Supón que tienes una aplicación Node.js corriendo en el puerto 3000 y quieres que Traefik la sirva. Primero comprueba que responde:
curl http://127.0.0.1:3000
# Hola desde Node.js detrás de Traefik
Crea un archivo de configuración dinámica:
sudo nano /etc/traefik/dynamic/node-hola.yml
http:
routers:
node-hola:
rule: "Host(`hola.localhost`)"
service: node-hola-svc
entryPoints:
- web
services:
node-hola-svc:
loadBalancer:
servers:
- url: "http://localhost:3000"
- router
node-hola: envía la petición al servicio cuando el encabezadoHostcoincide conhola.localhost. - service
node-hola-svc: apunta al backend enhttp://localhost:3000. - entryPoint
web: el router actúa sobre el puerto 80.
Para que hola.localhost resuelva en tu máquina, añade la entrada al archivo /etc/hosts:
127.0.0.1 hola.localhost
Reinicia el servicio y prueba:
sudo systemctl restart traefik
curl -v http://hola.localhost
- Si consultas la IP directamente, Traefik devuelve 404 porque ningún router coincide con ese host.
- Si consultas
hola.localhost, el routernode-holacoincide y reenvía a tu aplicación Node.js, devolviendo 200 OK.
Si prefieres que Traefik capture todo el tráfico del puerto 80 sin depender del host, usa un router catch-all con PathPrefix(/).
Reglas de enrutamiento (routers) más usadas
Traefik permite segmentar el tráfico con reglas flexibles. Estos son los patrones que más vas a necesitar:
Por Host (virtual hosting):
http:
routers:
host-router:
rule: "Host(`api.midominio.com`)"
service: api-svc
entryPoints: [web]
Por Path (ruta exacta) y PathPrefix (ruta y subrutas, ideal para APIs):
http:
routers:
prefix-router:
rule: "PathPrefix(`/api`)"
service: api-svc
entryPoints: [web]
Combinando Host + PathPrefix:
http:
routers:
combined-router:
rule: "Host(`api.midominio.com`) && PathPrefix(`/v2`)"
service: api-v2
entryPoints: [web]
Por método HTTP:
http:
routers:
post-router:
rule: "Method(`POST`)"
service: write-svc
entryPoints: [web]
Por encabezado (versionado o flags):
http:
routers:
header-router:
rule: "Headers(`X-Version`, `v2`)"
service: api-v2
entryPoints: [web]
Reescritura de URL (para servicios legacy):
http:
routers:
rewrite-router:
rule: "PathPrefix(`/api`)"
service: api-svc
entryPoints: [web]
middlewares: [rewrite]
middlewares:
rewrite:
replacePathPrefix:
prefix: "/api"
replacement: "/"
Middlewares: seguridad y transformaciones en capa 7
Los middlewares se ejecutan entre el router y el service. Estos son los más útiles:
Redirección HTTP → HTTPS (fuerza el cifrado):
http:
middlewares:
https-redirect:
redirectScheme:
scheme: https
permanent: true
Autenticación básica (protege rutas de administración):
http:
middlewares:
auth:
basicAuth:
users:
- "admin:$apr1$hashhashhash"
Rate limiting (protege contra abuso):
http:
middlewares:
limit:
rateLimit:
average: 50
burst: 100
CORS (controla qué orígenes acceden a la API):
http:
middlewares:
cors:
headers:
accessControlAllowOriginList:
- "https://midominio.com"
accessControlAllowMethods: ["GET", "POST"]
accessControlAllowHeaders: ["Content-Type", "Authorization"]
Balanceo de carga y despliegues Canary
El servicio con loadBalancer distribuye tráfico entre varios servidores:
http:
services:
node-lb:
loadBalancer:
servers:
- url: "http://localhost:3000"
- url: "http://localhost:3001"
Para Canary/Blue-Green, asigna un peso a cada grupo de servidores. Por ejemplo, el 90% del tráfico a la versión estable y el 10% a la nueva:
http:
services:
v1:
loadBalancer:
servers:
- url: "http://localhost:3000"
v2:
loadBalancer:
servers:
- url: "http://localhost:3002"
weighted:
weighted:
services:
- name: v1
weight: 90
- name: v2
weight: 10
Con healthCheck, Traefik deja de enviar tráfico a servicios caídos:
http:
services:
resilient:
loadBalancer:
servers:
- url: "http://localhost:5100"
healthCheck:
path: "/health"
interval: "10s"
timeout: "3s"
Proxy de Capa 4 y UDP: bases de datos y protocolos no HTTP
Cuando el tráfico no es HTTP (bases de datos, SSH, streaming, MQTT), Traefik trabaja a nivel de transporte: transmite los paquetes sin leer su contenido. En TCP puro no existe el concepto de dominio, por eso se usa la regla HostSNI(*).
Exponer una base de datos Redis interna a través de un puerto concreto:
# traefik.yml (configuración estática)
entryPoints:
redis-port:
address: ":6379"
# dynamic_config.yml
tcp:
routers:
to-redis:
entryPoints:
- "redis-port"
rule: "HostSNI(`*`)"
service: "redis-service"
services:
redis-service:
loadBalancer:
servers:
- address: "192.168.1.50:6379"
Casos de uso comunes en capa 4: bases de datos (MySQL, Postgres, MongoDB), streaming (RTMP), SSH y MQTT. Con TLS + SNI puedes multiplexar varios servicios TCP en un mismo puerto usando HostSNI(tu-dominio.com), y para protocolos UDP como WireGuard o juegos se usa la sección udp, que es una relación directa 1 a 1 entre puerto de entrada y servicio.
HTTPS con Let’s Encrypt: certificados automáticos
Traefik actúa como terminador TLS: el cifrado se establece entre el cliente y Traefik, no directamente con el backend. Para automatizar los certificados usa un CertResolver que se comunica con una Autoridad Certificadora mediante el protocolo ACME.
Configurar el resolver en la configuración estática
Añadimos el entrypoint HTTPS y el resolver de Let’s Encrypt:
entryPoints:
web:
address: ":80"
websecure:
address: ":443"
certificatesResolvers:
letsencrypt:
acme:
email: "tu-email@example.com"
storage: "/etc/traefik/acme.json"
httpChallenge:
entryPoint: web
El método de validación HTTP-01 pide a Let’s Encrypt que verifique el dominio por HTTP en el puerto 80. Por eso ese puerto debe estar accesible públicamente.
Activar TLS en un router
http:
routers:
miapp-https:
rule: "Host(`tudominio.com`)"
entryPoints: ["websecure"]
service: miapp
tls:
certResolver: letsencrypt
El flujo es: Traefik busca el router que coincide con Host(tudominio.com), ve el bloque tls: con certResolver: letsencrypt, pide el certificado a Let’s Encrypt por ACME, supera el challenge HTTP-01 y guarda el certificado en acme.json. A partir de ahí, HTTPS funciona siempre.
TLS on-demand: Traefik solo genera un certificado cuando existe un router válido para el dominio y recibe la primera petición HTTPS. No funciona de forma indiscriminada; requiere reglas explícitas.
Recomendaciones de seguridad TLS
Por defecto Traefik puede aceptar TLS 1.0 y 1.1, considerados inseguros. Para una buena calificación en SSL Labs:
tls:
options:
modern:
minVersion: VersionTLS12
Si prefieres usar certificados propios, se configuran en la dinámica con tls.certificates, indicando los archivos .crt y .key; Traefik los usa para cualquier router HTTPS sin certResolver y no intenta hablar con Let’s Encrypt.
Integración de Traefik con Docker
No importa si Traefik está en un contenedor o instalado en tu sistema: solo necesita acceso al socket de Docker, que es su API:
/var/run/docker.sock
Asegura los permisos y añade el provider en traefik.yml:
sudo usermod -aG docker traefik
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false
Con esto Traefik detecta contenedores, lee sus labels y crea routers, services y middlewares automáticamente. Los contenedores solo necesitan labels:
services:
miapp:
image: node:18
labels:
- "traefik.enable=true"
- "traefik.http.routers.miapp.rule=Host(`midominio.com`)"
- "traefik.http.routers.miapp.entrypoints=websecure"
- "traefik.http.routers.miapp.tls.certresolver=letsencrypt"
- "traefik.http.services.miapp.loadbalancer.server.port=3000"
Dashboard de Traefik: exponerlo y protegerlo
El dashboard es una interfaz HTTP que muestra el estado de entrypoints, routers, services, middlewares y certificados. Desde el punto de vista de red no es especial: es otro servicio HTTP interno bajo el nombre api@internal, así que se publica igual que cualquier otra app.
En la configuración estática se habilita con api.dashboard: true. Activarlo no lo hace accesible desde fuera: solo significa que Traefik puede enrutar hacia él.
En la dinámica definimos un router que apunte a api@internal:
http:
routers:
traefik-dashboard:
rule: "Host(`traefik.midominio.com`)"
entryPoints: [websecure]
service: api@internal
tls: {}
Para protegerlo, añadimos un middleware basicAuth:
http:
middlewares:
auth-traefik:
basicAuth:
users:
- "admin:$apr1$HASH..."
http:
routers:
traefik-dashboard:
rule: "Host(`traefik.midominio.com`)"
entryPoints: [websecure]
service: api@internal
tls: {}
middlewares:
- auth-traefik
Otra estrategia académicamente interesante es no exponerlo públicamente: define un entrypoint solo en 127.0.0.1:8080 y accede únicamente desde el propio host. Es defensa por aislamiento de red.
Traefik detrás de Cloudflare: qué modo SSL usar
Cuando pones Cloudflare delante de Traefik, aparecen dos puntos de terminación TLS: cliente ↔ Cloudflare y Cloudflare ↔ Traefik. Cloudflare ofrece tres modos:
- Flexible: cliente ↔ Cloudflare por HTTPS, pero Cloudflare → Traefik por HTTP. El origen no necesita certificado, pero rompe el cifrado extremo a extremo y complica la validación ACME. Evítalo.
- Full: ambos tramos cifrados, pero el certificado del origen puede ser autofirmado. Útil con certificados internos.
- Full (Strict): ambos tramos cifrados y con certificado válido y confiable en el origen. Es el modo recomendado si Traefik usa Let’s Encrypt: el cifrado es extremo a extremo, Cloudflare valida el certificado y ACME funciona sin problemas.
Conclusión
Traefik es la evolución natural del proxy inverso: se configura solo, descubre tus servicios dinámicamente y gestiona el HTTPS por ti. Ya sea con archivos locales, con Docker o detrás de Cloudflare, el modelo de EntryPoints → Routers → Middlewares → Services es coherente y fácil de depurar.
Si trabajas con despliegues propios, esta guía encaja con la de Dokploy, que usa Traefik como pieza interna para enrutar el tráfico de tus aplicaciones. Y si gestionas dominios y DNS desde Cloudflare, completa el puzzle con la guía de Despliegue Continuo en Cloudflare Pages. En el pilar de DevOps tienes el resto de la documentación sobre infraestructura y automatización.
Preguntas frecuentes
¿Qué es Traefik y para qué sirve?
Traefik es un proxy inverso y equilibrador de carga dinámico de código abierto. Recibe todo el tráfico de internet y lo enruta al servicio correspondiente según el dominio o la ruta solicitada. Su gran ventaja frente a Nginx o HAProxy es que se configura solo: descubre los servicios dinámicamente desde Docker, Kubernetes u otros proveedores, gestiona certificados SSL automáticos con Let's Encrypt y soporta HTTP/2 de forma nativa.
¿Cómo se compara Traefik con Nginx?
Ambos funcionan como proxy inverso, pero Traefik añade el concepto de "proveedores": escucha los eventos de Docker o Kubernetes y se autoconfigura cuando aparece o desaparece un contenedor, sin editar archivos ni recargar. Además incluye soporte nativo de HTTP/2, TLS automático con ACME y una configuración en YAML dividida en estática y dinámica, mientras que Nginx se configura manualmente con bloques server.
¿Qué son los EntryPoints, Routers, Middlewares y Services en Traefik?
Son los cuatro bloques que componen el flujo de una petición: los EntryPoints son los puertos por los que Traefik escucha (p. ej. 80 y 443); los Routers analizan cada petición con una regla (Host, PathPrefix, headers...) y deciden su destino; los Middlewares modifican la petición antes de llegar al backend (autenticación, CORS, rate limiting, redirecciones); y los Services definen hacia dónde se reenvía el tráfico, con balanceo de carga y healthchecks.
¿Cómo instalo Traefik en un servidor Linux?
La forma más limpia es como binario + servicio systemd: descargas el binario desde los releases oficiales de GitHub, le das permisos de ejecución con chmod, lo mueves a /usr/local/bin, creas el archivo de configuración estática en /etc/traefik/traefik.yml y defines un unit file de systemd. Así obtienes logs en journald, reinicios automáticos y control total, sin depender de Docker.
¿Cómo expongo una aplicación Node.js con Traefik?
Defines un archivo de configuración dinámica en /etc/traefik/dynamic con un router y un service. Por ejemplo, un router con la regla Host(`hola.localhost`) que apunta al service http://localhost:3000. Si la petición llega por ese dominio, Traefik reenvía el tráfico a tu aplicación; si llega por otra IP u otro host, devuelve 404.
¿Qué diferencia hay entre proxy de Capa 4 y Capa 7?
El proxy de Capa 4 (TCP) transmite los paquetes sin leer su contenido, ideal para bases de datos, SSH o WebSockets puros; usa la regla HostSNI(*) porque en TCP puro no existe el concepto de dominio. El proxy de Capa 7 (HTTP) termina el TLS, inspecciona la URL, cabeceras y cookies, y permite enrutamiento por path, headers o métodos, además de aplicar middlewares de seguridad.
¿Cómo configuro HTTPS con Let's Encrypt en Traefik?
Defines un certificatesResolver de tipo acme en la configuración estática (con email, storage y el método HTTP-01). Después, en los routers que quieras sirve HTTPS añades el bloque tls con certResolver: letsencrypt y los expones por el entryPoint websecure (443). Traefik pide, valida y renueva el certificado automáticamente.
¿Puedo integrar Traefik con Docker?
Sí. Traefik solo necesita acceso al socket de Docker (/var/run/docker.sock). Con el provider docker activado (exposedByDefault: false), lee las labels de los contenedores (traefik.enable, traefik.http.routers...) y crea automáticamente routers, services y middlewares para cada contenedor, incluso si Traefik está instalado fuera de Docker.
¿Qué es el dashboard de Traefik y cómo lo protejo?
El dashboard es una interfaz HTTP que expone el estado de entrypoints, routers, middlewares y certificados. Es otro servicio interno llamado api@internal: se publica igual que cualquier app, definiendo un router que apunte a él. Para protegerlo usas un middleware basicAuth (usuario + hash htpasswd) o lo restringes a localhost con un entryPoint en 127.0.0.1.
¿Qué modo SSL de Cloudflare debo usar con Traefik?
Si Cloudflare está delante de Traefik, evita el modo Flexible (deja el tramo Cloudflare→origen en HTTP y rompe ACME). Usa Full si el certificado del origen es autofirmado, o Full (Strict) si Traefik usa Let's Encrypt: así el cifrado es extremo a extremo, Cloudflare valida el certificado del origen y Let's Encrypt funciona sin problemas.