Cómo usar Traefik para compartir el puerto 80 entre varios proyectos Docker

Docker

Traefik es un proxy inverso que enruta el tráfico web a diferentes aplicaciones basándose en nombres de dominio. En lugar de acceder a tus proyectos usando diferentes puertos, como por ejemplo localhost:8080 o localhost:8081, puedes usar nombres de dominio como app1.localhost o app2.localhost, ambos en el puerto 80.

Traefik tiene una latencia mínima de alrededor de 1-5ms por petición y un bajo uso de CPU y de memoria, consumiendo solo entre 50 y 100 MB de RAM.

Requisitos previos

En este ejemplo usaré Docker en Windows mediante WSL2, pero puedes usar Linux o MacOS, ya que el proceso será el mismo. Lo único que necesitarás son conocimientos básicos de Docker y docker-compose. También necesitarás conocomientos de la línea de comandos. Si no los tienes, puedes consultar las siguientes guías:

Dicho esto, vamos a comenzar con la configuración inicial de Traefik.

Instala Traefik en un contenedor

Primero, necesitamos crear una red de Docker que compartirán todas nuestras aplicaciones. Para ello usa este comando:

docker network create traefik-network

Esta red permite que Traefik se comunique con todos tus contenedores.

Seguidamente crea una carpeta para Traefik, por ejemplo en el directorio /home/<usuario>/code/traefik/. Luego crea en su interior el archivo docker-compose.yml de Traefik con el siguiente contenido:

version: '3'

services:
  traefik:
    image: traefik:v2.10
    container_name: traefik
    ports:
      - "80:80"           # Puerto HTTP
      - "8080:8080"       # Panel de control de Traefik
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
    command:
      - "--api.insecure=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
    networks:
      - traefik-network
    restart: unless-stopped

networks:
  traefik-network:
    external: true
Desde la carpeta de Traefik, ejecuta este comando para iniciar el contenedor y Traefik:
docker-compose up -d

Luego ejecuta este comando para verificar que se esté ejecutando:

docker ps | grep traefik

Deberías ver algo como:

traefik   traefik:v2.10   "/entrypoint.sh ..."   Up 0.0.0.0:80->80/tcp, 0.0.0.0:8080->8080/tcp

Ahora, si accedes desde tu navegador a http://localhost:8080 deberías ver a interfaz de Traefik:

Con esto ya hemos terminado. ahora vamos a configurar un par de aplicaciones.

Cómo usar Traefik en dos aplicaciones

Para configurar la primera, vamos a dar por hecho que tienes un proyecto Laravel llamado «blog» que normalmente se ejecuta en el puerto 8080.

Encuentra el archivo docker-compose.yml de tu aplicación, que si usas nginx será más o menos como en este ejemplo:

services:
  app:
    image: nginx:latest
    container_name: blog_app
    ports:
      - "8080:80"  # Expuesto en el puerto 8080
    volumes:
      - ./:/var/www/html
    networks:
      - blog_network

networks:
  blog_network:
    driver: bridge

Debes hacer los siguientes cambios, eliminado la asignación de puertos, sin exponerlos, pero agregando las labels con el dominio que quieras usar y tambien la red de traefik:

services:
  app:
    image: nginx:latest
    container_name: blog_app

    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.blog.rule=Host(`blog.localhost`)"
      - "traefik.http.routers.blog.entrypoints=web"
      - "traefik.http.services.blog.loadbalancer.server.port=80"

    volumes:
      - ./:/var/www/html

    networks:
      - blog_network
      - traefik-network  # ¡Añade esto!

networks:
  blog_network:
    driver: bridge
  traefik-network:
    external: true

Vamos a explicar en detalle qué hace cada etiqueta:

La etiqueta "traefik.enable=true" le dice a Traefik que gestione este contenedor.

  • La etiqueta "traefik.http.routers.blog.rule=Host(`blog.localhost`)""traefik.enable=true" le dice a Traefik que gestione este contenedor.
  • La etiqueta "traefik.http.routers.blog.rule=Host(`blog.localhost`)" enruta el tráfico de blog.localhost a este contenedor. Cambia blog para que coincida con el nombre de tu aplicación.
  • La etiqueta "traefik.http.routers.blog.entrypoints=web" sirve para user el usar el puerto 80 como punto de entrada.
  • La etiqueta "traefik.http.services.blog.loadbalancer.server.port=80" le dice a Traefik en qué puerto escucha tu contenedor internamente, que generalmente es el puerto 80 para servidores web.

Ahora vamos vamos a agregar el dominio al archivo de host. En mi caso agregaré la siguiente línea en el archivo C:\Windows\System32\drivers\etc\hosts.txt de Windows:

127.0.0.1   blog.localhost

Luego reinicia tu aplicación desde el directorio donde la tengas instalada mediante los siguientes comandos o desde la interfaz de Docker:

docker-compose down
docker-compose up -d

Ahora, si accedes a tu aplicación desde la URL http://blog.localhost deberías ver la página de inicio de tu aplicación.

Vamos a configurar la segunda aplicación y para ello vamos a dar por hecho que la quieres en shop.localhost. Agrega esto en el docker-compose.yml de tu proyecto shop:

services:
  app:
    image: nginx:latest
    container_name: shop_app

    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.shop.rule=Host(`shop.localhost`)"  # ¡Nombre de router diferente!
      - "traefik.http.routers.shop.entrypoints=web"
      - "traefik.http.services.shop.loadbalancer.server.port=80"

    volumes:
      - ./:/var/www/html

    networks:
      - shop_network
      - traefik-network

networks:
  shop_network:
    driver: bridge
  traefik-network:
    external: true

Recueda cambiar el nombre del router de blog a shop en las etiquetas. Luego agrega otra línea al archivo de hosts, de modo que contenga:

127.0.0.1   blog.localhost
127.0.0.1   shop.localhost

No te olvides tampoco de reiniciar la aplicación:

docker-compose down
docker-compose up -d

Con esto ya hemos acabado. Si accedes a http://shop.localhost/ desde tu navegador deberías poder ver la página.

El patrón sería el mismo para agregar más aplicaciones. Eso sí, debes tener en cuenta que el nombre e las etiguetas y de los hosts debe ser único.

Cómo usar múltiples dominios en una aplicación

Puedes hacer que una aplicación responda a múltiples dominios:

labels:
  - "traefik.enable=true"
  - "traefik.http.routers.myapp.rule=Host(`myapp.localhost`) || Host(`app.localhost`) || Host(`www.localhost`)"
  - "traefik.http.routers.myapp.entrypoints=web"
  - "traefik.http.services.myapp.loadbalancer.server.port=80"

Añade todos los dominios a tu archivo hosts:

127.0.0.1   myapp.localhost
127.0.0.1   app.localhost
127.0.0.1   www.localhost

Cómo acceder al panel de control de Traefik

Visita http://localhost:8080 para acceder al panel de control, desde donde podrás ver:

  • Todas las rutas registradas
  • Los servicios activos
  • El tráfico en tiempo real
  • El estado de salud de los contenedores

Vamos a finalizar dando solución a una serie de problema comunes.

Solución de Problemas comunes de Traefik

A continuación explico cómo solucionar algunos problemas que quizás te encuentres:

  • Se muestra el mensaje «no se puede acceder al sitio» o «conexión rechazada»: Si te encuentras con este error, vertifica que Traefik se esté ejecutando mediante el comando docker ps | grep traefik. Si lo está, comprueba que esté conectada a la rer de Traefik usando el comando docker network inspect traefik-network. Deberías ver el contenedor de tu aplicación listado. También puedes realizar comprobaciones desde el panel de control de Traefik.
  • El dominio no se resulte: Prueba a limpiar la caché DNS de tu sistema operativo, que en Windows se hace con el comando ipconfig /flushdns. Verifica tambén que el dominio esté registado en el archivo de hosts existe. Intenta hacer ping al dominio mediante el comando ping blog.localhost, que debería responder en 127.0.0.1.
  • Si el pierto 80 ya está en uso: Detén cualquier otro servicio que esté usando el puerto 80 como IIS (Internet Information Services), Apache, Nginx u otros servidores web.
  • Si se muestra la página 404 de Traefik: Esto significa que Traefik está funcionando, pero no puede encontrar tu aplicación. Comprueba que las etiquetas en los archivos docker-compose.yml sean correctas. Comprueba también que tu contenedor se esté ejecutando docker ps. Reinicia tu aplicación después de añadir las etiquetas usandom docker-compose down y docker-compose up -d.

Vamos a terminar con una pequeña guía rápida de Traefik.

Cómo gestionar Traefik

Para uniciar Traefik sencillamente inicia el contenedor donde esté instalado:

cd /home/neeonez/code/traefik
docker-compose up -d

Para detener Traefik, detén el contenedor:

cd /home/neeonez/code/traefik
docker-compose down

Para ver los logs de Traefik usa este comando:

docker logs traefik

O para que se actualicen en tiempo real:

docker logs -f traefik # Seguir logs en tiempo real

Para reiniciar Traefik, simplemente reinicia el contenedor:

cd /home/neeonez/code/traefik
docker-compose restart

Puedes consultar más información en la documentación oficial de Traefik. Con esto ya hemos terminado.


Avatar de Edu Lazaro

Edu Lázaro: Ingeniero técnico en informática, actualmente trabajo como desarrollador web y programador de videojuegos.

👋 Hola! Soy Edu, me encanta crear cosas y he redactado esta guía. Si te ha resultado útil, el mayor favor que me podrías hacer es el de compatirla en Twitter 😊

Si quieres conocer mis proyectos, sígueme en Twitter.

Deja una respuesta

“- Hey, Doc. No tenemos suficiente carretera para ir a 140/h km. - ¿Carretera? A donde vamos, no necesitaremos carreteras.”