Enrutamiento HTTP con Traefik
Introducción
Durante el desarrollo local, es bastante común necesitar ejecutar múltiples servicios HTTP. Es posible que tengas tanto una API como una aplicación frontend, un servicio de WireMock para simular puntos finales de datos (endpoints) o un visualizador de base de datos (como phpMyAdmin o pgAdmin). En muchas configuraciones de desarrollo, estos servicios se exponen en diferentes puertos, lo que requiere que recuerdes qué puerto corresponde a cada servicio, pero también puede introducir otros problemas (como CORS).
Un proxy inverso puede simplificar enormemente esta configuración al ser el único servicio expuesto y enrutar las solicitudes al servicio adecuado según la URL de la solicitud (ya sea por ruta o por nombre de host). Traefik es un proxy inverso y balanceador de carga moderno y nativo de la nube que hace que el desarrollo y el despliegue de aplicaciones multiservicio sean más sencillos. Esta guía te mostrará cómo usar Traefik con Docker para mejorar tu entorno de desarrollo.
En esta guía, aprenderás a:
- Iniciar Traefik con Docker
- Configurar reglas de enrutamiento para dividir el tráfico entre dos contenedores
- Usar Traefik en un entorno de desarrollo contenedorizado
- Usar Traefik para enviar solicitudes a cargas de trabajo no contenedorizadas
Requisitos previos
Se requieren los siguientes requisitos previos para seguir esta guía práctica:
- Docker Desktop
- Node.js y yarn
- Conceptos básicos de Docker
Uso de Traefik con Docker
Una de las características únicas de Traefik es su capacidad para configurarse de muchas formas. Al utilizar el proveedor de Docker, Traefik obtiene su configuración de otros contenedores en ejecución mediante etiquetas (labels). Traefik monitoreará los eventos del motor (para inicios y paradas de contenedores), extraerá las etiquetas y actualizará su configuración.
Aunque existen muchas etiquetas monitoreadas por Traefik, las dos más comunes serán:
traefik.http.routers.<nombre-del-servicio>.rule: utilizada para indicar la regla de enrutamiento (consulta todas las reglas disponibles aquí)traefik.http.services.<nombre-del-servicio>.loadbalancer.server.port: indica el puerto al que Traefik debe reenviar la solicitud. Ten en cuenta que este puerto del contenedor no necesita estar expuesto en tu máquina host (lee sobre la detección de puertos aquí)
Hagamos una demostración rápida de cómo iniciar Traefik y luego configurar dos contenedores adicionales para que sean accesibles utilizando diferentes nombres de host.
Para que dos contenedores puedan comunicarse entre sí, deben estar en la misma red. Crea una red llamada
traefik-demoutilizando el comandodocker network create:$ docker network create traefik-demoInicia un contenedor Traefik utilizando uno de los siguientes métodos. Estos comandos exponen Traefik en el puerto 80, montan el socket de Docker (que se utiliza para monitorear los contenedores para actualizar la configuración) y pasan el argumento
--providers.dockerpara configurar Traefik para que use el proveedor de Docker.Las imágenes protegidas de Docker (Docker Hardened Images - DHI) para Traefik están disponibles en Docker Hub. Si aún no te has autenticado, primero ejecuta:
$ docker login dhi.ioLuego inicia un contenedor utilizando la imagen Hardened:
$ docker run -d --network=traefik-demo \ -p 80:80 \ -v /var/run/docker.sock:/var/run/docker.sock \ dhi.io/traefik:3.6.2 \ --providers.dockerTambién puedes usar la imagen oficial de Docker Hub:
$ docker run -d --network=traefik-demo \ -p 80:80 \ -v /var/run/docker.sock:/var/run/docker.sock \ traefik:v3.6.2 \ --providers.dockerAhora, inicia un contenedor Nginx simple y define las etiquetas que Traefik está monitoreando para configurar el enrutamiento HTTP. Ten en cuenta que el contenedor Nginx no expone ningún puerto.
Las imágenes protegidas de Docker (DHI) para Nginx están disponibles en Nginx DHI image. Si aún no te has autenticado, primero ejecuta:
$ docker login dhi.io$ docker run -d --network=traefik-demo \ --label 'traefik.http.routers.nginx.rule=Host(`nginx.localhost`)' \ dhi.io/nginx:1.29.3También puedes ejecutar la imagen oficial de Nginx de la siguiente manera:
$ docker run -d --network=traefik-demo \ --label 'traefik.http.routers.nginx.rule=Host(`nginx.localhost`)' \ nginx:1.29.3Una vez que el contenedor se inicie, abre tu navegador en http://nginx.localhost para ver la aplicación (todos los navegadores basados en Chromium enrutan las solicitudes
*.localhostlocalmente sin necesidad de configuración adicional).Inicia una segunda aplicación que utilizará un nombre de host diferente.
$ docker run -d --network=traefik-demo --label 'traefik.http.routers.welcome.rule=Host(`welcome.localhost`)' docker/welcome-to-dockerUna vez que el contenedor se inicie, abre tu navegador en http://welcome.localhost. Deberías ver un sitio web "Welcome to Docker".
Uso de Traefik en desarrollo
Ahora que has probado Traefik, es hora de intentar usarlo en un entorno de desarrollo. En este ejemplo, utilizarás una aplicación de ejemplo que tiene un frontend y un backend divididos. Esta pila de aplicaciones tiene la siguiente configuración:
- Todas las solicitudes a /api van al servicio API.
- Todas las demás solicitudes a localhost van al cliente frontend.
- Dado que la aplicación utiliza MySQL, db.localhost debería proporcionar phpMyAdmin para facilitar el acceso a la base de datos durante el desarrollo.

Se puede acceder a la aplicación en GitHub en dockersamples/easy-http-routing-with-traefik.
En el archivo
compose.yaml, Traefik está utilizando la siguiente configuración:services: proxy: image: dhi.io/traefik:3.6.2 command: --providers.docker ports: - 80:80 volumes: - /var/run/docker.sock:/var/run/docker.sockservices: proxy: image: traefik:v3.6.2 command: --providers.docker ports: - 80:80 volumes: - /var/run/docker.sock:/var/run/docker.sockTen en cuenta que esta es esencialmente la misma configuración que se usó anteriormente, pero ahora con la sintaxis de Compose.
El servicio client tiene la siguiente configuración, que iniciará el contenedor y le proporcionará las etiquetas para recibir solicitudes en localhost.
Las imágenes protegidas de Docker (DHI) para Nginx están disponibles en Nginx DHI image.
Si aún no te has autenticado, primero ejecuta:
$ docker login dhi.ioPuedes usarlo como tu imagen base como se muestra a continuación:
services: # … client: image: dhi.io/nginx:1.29.3-alpine3.21 volumes: - "./client:/usr/share/nginx/html" labels: traefik.http.routers.client.rule: "Host(`localhost`)"services: # … client: image: nginx:1.29.3-alpine3.22 volumes: - "./client:/usr/share/nginx/html" labels: traefik.http.routers.client.rule: "Host(`localhost`)"El servicio api tiene una configuración similar, pero notarás que la regla de enrutamiento tiene dos condiciones: el host debe ser "localhost" y la ruta de la URL debe tener el prefijo "/api". Dado que esta regla es más específica, Traefik la evaluará primero en comparación con la regla del cliente.
services: # … api: build: ./dev/api volumes: - "./api:/var/www/html/api" labels: traefik.http.routers.api.rule: "Host(`localhost`) && PathPrefix(`/api`)"Y finalmente, el servicio
phpmyadminestá configurado para recibir solicitudes para el nombre de host "db.localhost". El servicio también tiene variables de entorno definidas para iniciar sesión automáticamente, haciendo que sea un poco más sencillo ingresar a la aplicación.services: # … phpmyadmin: image: phpmyadmin:5.2.1 labels: traefik.http.routers.db.rule: "Host(`db.localhost`)" environment: PMA_USER: root PMA_PASSWORD: passwordAntes de iniciar la pila, detén el contenedor Nginx si aún se está ejecutando.
Y eso es todo. Ahora, solo necesitas poner en marcha la pila de Compose con
docker compose upy todos los servicios y aplicaciones estarán listos para el desarrollo.
Enviar tráfico a cargas de trabajo no contenedorizadas
En algunas situaciones, es posible que desees reenviar solicitudes a aplicaciones que no se ejecutan en contenedores. En el siguiente diagrama de arquitectura, se utiliza la misma aplicación de antes, pero la API y las aplicaciones de React ahora se ejecutan de forma nativa en la máquina host.

Para lograr esto, Traefik necesitará usar otro método para configurarse. Con el proveedor File puedes definir las reglas de enrutamiento en un documento YAML. Aquí tienes un archivo de ejemplo:
http:
routers:
native-api:
rule: "Host(`localhost`) && PathPrefix(`/api`)"
service: native-api
native-client:
rule: "Host(`localhost`)"
service: native-client
services:
native-api:
loadBalancer:
servers:
- url: "http://host.docker.internal:3000/"
native-client:
loadBalancer:
servers:
- url: "http://host.docker.internal:5173/"Esta configuración indica que las solicitudes para localhost/api se reenviarán a un servicio llamado native-api, que luego reenvía la solicitud a http://host.docker.internal:3000. El nombre de host host.docker.internal es un nombre que proporciona Docker Desktop para enviar solicitudes a la máquina host.
Con este archivo, el único cambio es en la configuración de Compose para Traefik. Específicamente, han cambiado dos cosas:
- El archivo de configuración se monta dentro del contenedor Traefik (la ruta de destino exacta depende de ti).
- Se actualiza el comando (
command) para añadir el proveedor file y apuntar a la ubicación del archivo de configuración.
services:
proxy:
image: dhi.io/traefik:3.6.2
command: --providers.docker --providers.file.filename=/config/traefik-config.yaml --api.insecure
ports:
- 80:80
- 8080:8080
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./dev/traefik-config.yaml:/config/traefik-config.yamlservices:
proxy:
image: traefik:v3.6.2
command: --providers.docker --providers.file.filename=/config/traefik-config.yaml --api.insecure
ports:
- 80:80
- 8080:8080
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./dev/traefik-config.yaml:/config/traefik-config.yamlIniciar la aplicación de ejemplo
Para ejecutar la aplicación de ejemplo que reenvía solicitudes de Traefik a aplicaciones que se ejecutan de forma nativa, realiza los siguientes pasos:
Si aún tienes la pila de Compose en ejecución, deténla con el siguiente comando:
$ docker compose downInicia la aplicación utilizando el archivo
compose-native.yamlproporcionado:$ docker compose -f compose-native.yaml upAl abrir http://localhost se devolverá un error "502 Bad Gateway" porque las otras aplicaciones aún no se están ejecutando.
Inicia la API ejecutando los siguientes pasos:
cd api yarn install yarn devInicia el frontend ejecutando los siguientes pasos en una nueva terminal (comenzando desde la raíz del proyecto):
cd client yarn install yarn devAbre la aplicación en http://localhost. Deberías ver una aplicación que recupera un mensaje de http://localhost/api/messages. También puedes abrir http://db.localhost para ver o ajustar los mensajes disponibles directamente desde la base de datos Mongo. Traefik se asegurará de que las solicitudes se enruten correctamente al contenedor o aplicación correctos.
Cuando hayas terminado, ejecuta
docker compose downpara detener los contenedores y detén las aplicaciones de Yarn presionandoctrl+c.
Resumen
Ejecutar múltiples servicios no tiene por qué requerir una configuración complicada de puertos y una buena memoria. Con herramientas como Traefik, es sencillo lanzar los servicios que necesitas y acceder a ellos sin complicaciones, ya sea para la aplicación en sí (como el frontend y el backend) o para herramientas de desarrollo adicionales (como phpMyAdmin).