Tutorial: Configurar traefik en docker-swarm con let's encrypt.

Buenas tardes compañeros, estoy configurando poco a poco un home server con varios servicios en local, lo que más me ha dado dolores de cabeza ha sido traefik, porque hay mucha documentación por internet, pero desactualizada (versiones antiguas) pero la mejor que he podido encontrar es la de atareado, cuya lectura recomiendo si se quiere entender más en profundidad acerca de cómo funciona y cómo añadir más servicios que el http y el https:
https://atareao.es/tutorial/traefik/

Este "tutorial" no es más que exponer mi configuración de traefik para que quién no tenga tiempo de entretenerse o simplemente quiera lanzar el contenedor básico, pueda hacerlo de forma fácil entendiendo lo que hace.

Necesitaremos:
- docker
- docker-compose
- Un dominio (miurl.com usado de ejemplo) y un subdominio (traefik.miurl.com) para ver el dashboard (se puede hacer sin dominio ni subdominio, siempre que editemos el archivo host de nuestro ordenador, pero sólo nos servirá a nosotros)
- Una network de overlay en docker (docker network create -d overlay traefik-public)
- /home/user/docker/traefik.yml ## Archivo necesario para levantar el servicio de traefik
- /home/user/docker/volumes/traefik/traefik.yml ## Archivo que contienen la configuración que carga traefik al arrancar

En mi caso, no uso docker-compose directamente, si no a través de portainer, un gestor de docker/docker-swarm (entre otros), aún así daré las instrucciones para docker-compose. Se asumirá que el usuario es "user", por lo que su home es /home/user. cambialo dónde te sea necesario.

En /home/user/docker crearemos el archivo traefik.yml y usaremos la siguiente configuración:
version: "3.7"

services:
  traefik:
    image: traefik:v2.9 # así siempre cargará la última 2.9 disponible, sin saltar a la versión 3 cuando salga
    ports:
      - target: 80
        published: 80
        protocol: tcp
        mode: host # En docker-swarm es necesario esto para que reciba bien las cabeceras de IP, de otro modo, todas las peticiones le parecerá que vienen de la red de ingress y no de fuera.
      - target: 443
        published: 443
        protocol: tcp
        mode: host
    volumes:
# Mapeamos:
# La API interna de docker, para que traefik descubra nuevos contenedores
# Un directorio para almacenar un .json que contendrá los certificados SSL generados por let's encrypt.
# La configuración de traefik
# El timezone del host, para que el contenedor tenga la misma hora.
      - /var/run/docker.sock:/var/run/docker.sock
      - /etc/letsencrypt:/letsencrypt
      - /home/user/docker/volumes/traefik:/etc/traefik
      - /etc/timezone:/etc/timezone:ro
    networks:
      - traefik-public
    deploy:
      placement:
        constraints: [node.role == manager] #aunque esto no es necesario, porque sólo tenemos un nodo, podemos agregar más nodos y funcionará, siempre que haya un único manager.
      labels:
        - "traefik.enable=true" # habilitamos este contenedor en traefik para habilitar el dashboard
        - "traefik.http.routers.traefik-secure.rule=Host(`traefik.miurl.com`)" #cambiar por tu dominio # url por la que entraremos al dashboard
        - "traefik.http.services.traefik-secure.loadbalancer.server.port=8080" # Loadbalancer de mentira para docker swarm, omitir si sólo usamos docker
        - "traefik.http.routers.traefik-secure.service=api@internal" #Le indicamos a qué servicio apuntat traefik las llamadas a traefik.miurl.com, en estet caso, apunta a la api de traefik
        - "traefik.http.routers.traefik-secure.middlewares=ip-list" # Creamos un middleware, que usaremos para limitar las IPs que serán ruteadas a nuestro servicio de dashboard
        - "traefik.http.middlewares.ip-list.ipwhitelist.sourcerange=192.168.1.0/24" # Le indicamos al middleware el rango de IPs que pueden acceder al servicio de dashboard, usad el vuestro de casa, usad "ip a" en linux o "ipconfig" en windows para ver vuestra IP local.
       
# Aquí definimos la red traefik-public que usamos en este yml:
networks:
  traefik-public:
    external: true
    driver: overlay
    name: traefik-public


Ahora sólo nos queda definir nuestra configuración de traefik, el archivo /home/user/docker/volumes/traefik/traefik.yml:
entryPoints:
#habilitamos dos entrypoints, el web para http y el websecure para https, además añadimos redirección forzosa de http a https
  web:
    address: ":80"
    http:
      redirections:
        entryPoint:
          to: websecure
          scheme: https
  websecure:
    address: ":443"
    http:
      tls:
        certResolver: le

# Habilitamos la API de traefik y el dashboard
api:
  insecure: true
  dashboard: true

# Le indicamos el proveedor, en nuestro caso docker, en modo swarm, si sólo usas docker, elimina el swarmmode.
providers:
  docker:
    swarmmode: true
    exposedbydefault: false
    endpoint: "unix:///var/run/docker.sock"
    network: traefik-public

# Habilitamos los logs por stdout
log:
  level: ERROR

# Habilitamos los logs de acceso http/s por stdout
accesslog: {}

# Creamos el cert resolver "le" (sólo es un nombre) y lo configuramos
certificatesResolvers:
  le:
    acme:
      email: miemail@email.com # usar nuestro email real ya que así letsencrypt nos avisará de cualquier cambio en sus políticas.
      storage: /letsencrypt/acme.json # Path DENTRO del contetnedor donde se almacenan los certificados
      httpChallenge:
        entryPoint: web


Por últitmo para levantarlo en nuestro host, usamos
docker-compose -f /home/user/docker/traefik.yml up


Y para finalizar, para añadir una ruta a cualquier contenedor en traefik, sólo tenéis que añadir 3 labels en vuestros .yml de los servicios (atentos porque las labels van dentro de "deploy", si no, no funciona). Por ejemplo:

Archivo /home/user/docker/apache.yml
webapp:
  image: httpd
deploy:
  labels:
      - "traefik.enable=true" # Habilitamos traefik para este contenedor
      - "traefik.http.routers.apache.rule=Host(`apache.miurl.com`)" # Le indicamos la URL por la que vendrán las peticiones a traefik
      - "traefik.http.services.apache.loadbalancer.server.port=80" # Le indicamos a Traefik el puerto donde el contenedor expone el servicio.


Arrancamos el servicio apache:
docker-compose -f /home/user/docker/apache.yml up

Y si ahora vamos a http://apache.miurl.com veremos como nos redirecciona a https y nos expone el servicio de apache.

Como comento, no soy un experto, pero si alguien tiene dudas o necesita ayuda, que no dude en preguntar [beer]
0 respuestas