Ya para ir terminando esta seria de cuatro guías, desde la que empezamos con nuestro primer tutorial sobre la instalación de Docker en nuestra Raspberry Pi, su segunda parte donde aprendemos a configurar Home Assistant + MQTT y la tercera parte centrada en la instalación y configuración de Dockermon y Traccar hoy explicaremos cómo instalar el contenedor de Traefik, el cual nos permitirá montar un reverse-proxy en nuestro sistema.
Con un proxy inverso logramos que todas las solicitudes dirigidas a los servicios que tenemos instalados sean gestionadas por el propio proxy. Este se encarga de recibir y enviar la información necesaria al navegador web. Una de sus ventajas es permitir el acceso a múltiples servicios en nuestro hogar, manteniendo solo el puerto de Traefik abierto. Además, con este tutorial, Traefik generará certificados a través de Let's Encrypt para garantizar conexiones SSL seguras. Antes de empezar con el tutorial aquí tenéis los requisitos que necesitáis para llevarlo a cabo. Para el tutorial se utiliza la imagen oficial de traefik por lo que debería funciona en todos los sistemas operativos aunque actualmente solo se ha testado en raspberry pi, synology y Orange pi.
El puerto 80 lo vamos a utilizar para redirigir con traefik todo el tráfico que entre por http al puerto 443(https) y poder tener certificados de seguridad y toda la información que se envié encriptada. Para este tutorial vamos a utilizar el user Domology, pero vosotros podéis crear uno nuevo o utilizar alguno existente y como novedad que no habíamos visto hasta ahora en esta serie de tutoriales es que vamos a utilizar docker-compose para crear nuestro contenedor. Lo primero es loguearnos a nuestro host por ssh y creamos el usuario y lo añadimos al grupo docker:
1 2 3 4 |
useradd -m -s /bin/bash Domology usermod -aG docker Domology #reiniciamos docker systemctl restart docker |
Lo siguiente que vamos a hacer es crear una red virtual dentro de docker para asignársela a traefik
1 |
docker network create traefik |
Vamos a crear el password para poder acceder al dashboard de traefik, para hacerlo más seguro lo haremos de la forma hash:
1 2 3 4 |
#si no lo tenemos intalado sudo apt install apache2-utils -y #creamos el psswd htpasswd -nb Domology domologypassword |
La consola nos entregará nuestro usuario y password en este formato: DOMOTICA:$apr1$hEgpZUN2$OYG3KwpzI3T1FqIg9LIbi.
Copiamos y y guardamos el password ya que lo necesitaremos más adelante. Ahora empieza la chicha y vamos a crear los directorios de traefik y sus archivos de configuración:
1 2 3 4 5 6 7 8 |
#logueamos con nuestro usuario su - Domology #Creamos directorios de trabajo mkdir -p traefik/ cd traefik/ #creamos el archivo de configuracion de traefik nano traefik.toml |
Una vez dentro del archivo .toml nos dirigimos a github - traefik Copiamos en nuestro archivo la configuración y rellenamos con nuestros datos estos parámetros:
Llega el turno de preparar el script que usaremos con docker-compose para levantar nuestro container:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
version: '3' services: traefik: image: traefik:latest command: --docker --docker.domain=domology.es ports: - 80:80 - 443:443 networks: - traefik volumes: - /var/run/docker.sock:/var/run/docker.sock - ./traefik.toml:/traefik.toml - ./acme.json:/acme.json labels: - "traefik.frontend.rule=Host:traefik.domology.es" - "traefik.port=8080" container_name: traefik restart: always networks: traefik: external: true |
Si habéis seguido los demás tutoriales ya estáis familiarizados con la mayoría del código anterior, lo único nuevo que se añade es el apartado networks, donde pondremos la red virtual que creamos al principio del post y las labels o etiquetas, con ellas en este caso concreto le estamos indicando a traefik que puerto será el dashboard(8080) y cual será la dirección desde la que accederemos al mismo. Lo último que nos queda antes de levantar el container es crear el archivo donde lets encrypt guardará los certificados SSL:
1 2 |
touch acme.json chmod 600 acme.json |
Lo único que hacemos es crear un archivo de extensión .json vacio y darle los permisos correspondientes para que lets encrypt genere y escriba los certificados dentro del archivo. Ya finalmente toca el momento clave, poner a funcionar el container y para ellos ejecutamos la siguiente orden:
1 |
docker-compose up -d |
Con ello crearemos el container de traefik y si todo ha ido bien podremos entrar al dashboard del mismo en la dirección que indicamos en las etiquetas. Logueais poniendo vuestro usuario y contraseña, con la configuración de este tutorial se os crearan los backends de todos los containers que tengáis funcionando, pero no serán accesibles, simplemente lo único que hace es crear certificados por si queremos añadir dichos servicios. Para poder acceder desde fuera de nuestra red tenemos dos opciones, la primera si usáis docker-compose es añadir las siguientes etiquetas a la hora de crear el container:
1 2 3 4 |
labels: - "traefik.enable=true" - "traefik.frontend.rule=Host:servicio.tudominio.com" - "traefik.port=8089" |
Si no usáis la etiqueta "trafik.enable" , el proxy no accederá a vuestro servicio y no podréis utilizarlo desde fuera de la red. Para los que useis la consola para levantar los container las equitetas se ponen de la siguiente forma:
1 2 3 |
-l "traefik.enable=true" -l "traefik.frontend.rule=Host:servicio.tudominio.com" -l "traefik.port=8089" |
Por último la siguiente forma es añadir a la configuración de traefik reglas para indicarles que servicios van a ir por detrás de él, este método es aplicable para cualquier servicio que esté corriendo en vuestro ordenador aunque no esté como un container. Las reglas se añaden de la siguiente manera en el archivo traefik.toml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
[file] [backends] [backends.backend-homeassistant] [backends.backend-homeassistant.servers] [backends.backend-homeassistant.servers.server-homeassistant-ext] url = "http://192.168.0.20:8123" weight = 0 [frontends] [frontends.frontend-homeassistant] backend = "backend-homeassistant" passHostHeader = true # basicAuth = [ # HTTP Authentication # "xxx:yyyyyyyyyyyy", # ] [frontends.frontend-homeassistant.routes] [frontends.frontend-homeassistant.routes.route-homeassistant-ext] rule = "Host:homeassistant.TUDOMINIO.com" |
En este caso hemos añadido home assitant que debido a la necesidad que tiene de acceder a toda la red local para usar el discovery la mejor solución es levantarlo de forma normal y crear una regla para que se acceder mediante el proxy, si no lo hacemos así se pierde la capacidad del discovery. Cada regla que queráis crear tened en cuenta que dentro del código la parte de los backends deben ir juntos y la parte de los frontends juntos. Pues hasta aquí el tutorial para instalar un proxy reverso en vuestros ordenadores y pasar servicios por detrás de él. Si queréis más información y opciones de configuración aquí tenéis la documentación oficial de traefik
Actualización de la v1 a la v2 de traefik, que trae muchas novedades y nuevas funcionalidades pero también cambios importantes que hacen que la configuración desde la v1 no sea compatible y sea necesario cambiar ciertas cosas. De hecho hay una entrada en la documentación oficial dedicada a la migración de v1 a v2. Además también tienen una herramienta, que no la he probado.
Lo que conviene tener claro son los 5 conceptos que usa traefik para que podamos buscar lo que necesitamos en la documentación en el caso de necesitarlo:
A continuación vamos a ver como realizar la configuración, para lo que se puede llevar a cabo principalmente de dos maneras (hablando de servicios en docker), por un lado podemos crear un archivo de configuración y por otro podemos añadir etiquetas (labels) al levantar el contenedor. Con cualquiera de ellas tendremos el mismo comportamiento final. Hay cierta configuración estática que se puede combinar entre modo fichero y modo labels. Por lo que yo he estado probando, lo referente a entrypoints, logs, providers, configuración global y api (dashboard) se puede dejar en el fichero y luego usar labels para crear las reglas, pero jugando con las configuraciones me he encontrado problemas con los siguientes casos:
La siguiente configuración es flexible, pudiendo personalizar algunas opciones o cambiar el nombre, por ejemplo a los entrypoints, le puedes llamar web al http o cualquier otro nombre, así como ciertas rutas. Asi quedaría el fichero traefik.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
global: checkNewVersion: true sendAnonymousUsage: false entryPoints: http: address: ":80" https: address: ":443" certificatesResolvers: duckdns: acme: email: EMAIL@DOMAIN.com storage: /acme.json httpChallenge: entryPoint: http api: insecure: true dashboard: true providers: docker: exposedByDefault: false file: filename: /etc/traefik/dyn-config.yml watch: true |
Ésta sería un ejemplo de configuración mínima que deberíamos tener para poder crear servicios y routers. Si os habeis fijado la estructura del fichero ha cambiado con respecto al ejemplo de la guia para traefik v1. En este caso se un fichero formato yml. También es valido el formato toml, pero ya que estaba en la otra parte así lo dejamos de las dos maneras y que cada uno elija con la que más cómodo se encuentre. En el apartado de providers, vemos que tenemos docker y file, si solo vamos a usar uno de ellos podemos eliminar el otro. Así como añadir alguna otra configuración adicional o modificar los valores por defecto de otros parámetros. Siguiendo con la configuración del fichero (dyn-config.yml) ésta seria la estructura de cómo quedaría el servicio de home assistant con redireccion del puerto 80 al 443 y creación de certificado:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
http: services: homeAssistant: loadBalancer: servers: - url: "http://192.168.0.5:8123" routers: ha-http: entryPoints: - http service: homeAssistant middlewares: - redirect rule: "Host(`ha.domology.com`)" ha-https: entryPoints: - https service: homeAssistant rule: "Host(`ha.domology.com`)" tls: certResolver: middlewares: redirect: redirectScheme: scheme: https |
Si queremos crear toda la configuración con labels sería de la siguiente manera:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
traefik: container_name: traefik image: traefik restart: always command: - "--api.insecure=true" - "--providers.docker=true" - "--providers.docker.exposedbydefault=false" - "--entrypoints.http.address=:80" - "--entrypoints.https.address=:443" - "--certificatesresolvers.duckdns.acme.httpchallenge=true" - "--certificatesresolvers.duckdns.acme.httpchallenge.entrypoint=http" - "--certificatesresolvers.duckdns.acme.email=EMAIL@DOMAIN.com" - "--certificatesresolvers.duckdns.acme.storage=/acme.json" ports: - 80:80 - 443:443 - 8080:8080 volumes: - /var/run/docker.sock:/var/run/docker.sock - /docker/traefik/traefik.yml:/etc/traefik/traefik.yml - /docker/traefik/dyn-config.yml:/etc/traefik/dyn-config.yml - /docker/traefik/acme.json:/acme.json labels: - "traefik.enable=false" environment: - TZ=${TZ} portainer: container_name: Portainer image: portainer/portainer command: -H unix:///var/run/docker.sock restart: always ports: - 9000:9000 volumes: - /var/run/docker.sock:/var/run/docker.sock - /media/data/docker/portainer:/data - /etc/localtime:/etc/localtime:ro labels: - "traefik.enable=true" - "traefik.http.routers.portainer-http.rule=Host(`portainer.domology.com`)" - "traefik.http.routers.portainer-http.entrypoints=http" - "traefik.http.middlewares.redirectscheme.redirectscheme.scheme=https" - "traefik.http.routers.portainer-http.middlewares=redirectscheme" - "traefik.http.routers.portainer-https.rule=Host(`portainer.domology.com`)" - "traefik.http.routers.portainer-https.entrypoints=https" - "traefik.http.routers.portainer-https.tls=true" - "traefik.http.routers.portainer-https.tls.certresolver=duckdns" environment: - TZ=${TZ} |