· 3 min de lectura

Cómo funciona este servidor

Traefik como reverse proxy único, Docker como runtime, y un patrón declarativo para levantar servicios nuevos en minutos.

#infra#traefik#docker

Este host es, conceptualmente, bastante simple: un único proceso reverso que recibe todo el tráfico HTTPS y lo redirige al container correcto. El resto es declaración.

Las piezas

  • Traefik corre como único proceso expuesto a internet. Escucha en los puertos 80 y 443, termina TLS y enruta por nombre de host.
  • Docker corre todos los servicios. Cada servicio vive en su propio container, expuesto solo en la red interna web.
  • Let's Encrypt emite y renueva certificados automáticamente. Traefik se encarga.
  • Authelia (opcional, por servicio) añade una capa de login cuando hace falta.

El modelo mental es: Traefik es el único componente que toca internet. Todo lo demás vive en una red privada y nunca se expone al exterior excepto a través del proxy.

Diagrama: del request al servicio. Cliente hace HTTPS, Traefik matchea el host, redirige al container correspondiente en la red web.
Diagrama: del request al servicio. Cliente hace HTTPS, Traefik matchea el host, redirige al container correspondiente en la red web.

Cómo descubre Traefik los servicios

Traefik no tiene un archivo de configuración donde listar cada servicio. En su lugar, inspecciona los containers Docker que están conectados a la red web y lee sus labels. Cada servicio declara su propia configuración de routing.

Ejemplo para un sitio estático nuevo:

services:
  blog-web:
    image: blog-web:latest
    networks:
      - web
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.blog.rule=Host(`blog.example.com`)"
      - "traefik.http.routers.blog.entrypoints=websecure"
      - "traefik.http.routers.blog.tls.certresolver=letsencrypt"

Con eso alcanza. Traefik ve el container, lee las labels, crea el router, obtiene el certificado, y el sitio queda disponible en HTTPS. Sin tocar un solo archivo de configuración central.

El flujo de deploy

Diagrama: deploy de un servicio nuevo. compose file → docker compose up → Traefik descubre → Let's Encrypt emite cert → HTTPS activo.
Diagrama: deploy de un servicio nuevo. compose file → docker compose up → Traefik descubre → Let's Encrypt emite cert → HTTPS activo.

El patrón se repite siempre:

  1. Editás un docker-compose.yml con la imagen, la red y las labels del servicio nuevo.
  2. docker compose up -d --build lo levanta y lo conecta a la red web.
  3. Traefik detecta el container nuevo y crea el router correspondiente.
  4. Let's Encrypt emite el certificado la primera vez que hay tráfico.
  5. DNS wildcard (*.example.com apuntando al host) hace que el subdominio resuelva sin tocar el proveedor de DNS.

Total: editar un YAML y correr un comando. El TLS, el routing y el descubrimiento salen solos.

Por qué funciona tan bien

Tres razones, en orden de importancia:

  • Es declarativo: el estado deseado está en archivos. Si borrás el container, Traefik lo desregistra. Si lo volvés a levantar, reaparece. No hay drift entre lo que querés y lo que tenés.
  • Es componible: agregar un servicio nuevo no rompe los existentes. Cada uno declara su propia configuración de routing en sus propias labels.
  • Es observable: Traefik expone una API y un dashboard donde ves todos los routers activos, sus reglas, los certificados y el estado de cada backend. Cuando algo no anda, la respuesta suele estar a un GET de distancia.

Las pocas cosas que NO son automáticas

  • El DNS wildcard hay que configurarlo una vez en el proveedor. Después, todos los subdominios nuevos resuelven solos.
  • Authelia requiere agregar una label extra si querés que el servicio quede protegido por login. Hay un patrón estándar: "traefik.http.routers.<svc>.middlewares=authelia@docker" y listo.
  • Backups de los volúmenes persistentes no están automatizados. Es trabajo manual, y, siendo honesto, es deuda pendiente.

Cómo luce el repo de un servicio

Cada sitio o app vive en su propia carpeta bajo un directorio común, con su propio docker-compose.yml, su Dockerfile, y (si corresponde) su código fuente. Ejemplo:

/workspace/blog/
├── docker-compose.yml
├── Dockerfile.web
├── nginx.conf
├── posts/
└── public/

El patrón es consistente entre todos los servicios del host. Cuando aprendés uno, aprendés todos. Cuando arreglás un patrón roto, lo arreglás en un lugar y queda arreglado en todos.