Traefik, le reverse-proxy HTTPS pour containers Docker

Auto-hébergement

Dans le précédent article sur Docker, je vous expliquais comment gérer des services auto-hébergés avec Docker. Dans celui-ci je vais vous montrer comment gérer l’exposition de mes services sur internet, et avoir un certificat Let’s encrypt pour chaque sous-domaine.

Pré-requis

Vous devrez avoir une box internet déjà configurée pour faire du NAT. Je ne vais pas aborder cela dans cet article, mais il faut que la machine qui héberge vos containers soit accessible de l’éxtérieur de votre réseau local sur le port 80. Il faudra bien sûr, un nom de domaine public pour que Let’s Encrypt puisse le valider.
Et je ne serai trop vous recommander d’avoir parcouru le premier article sur Docker.

Traefik

Comme je le disais en conclusion du premier article, le seul moyen d’accéder aux services hébergés avec Docker était de saisir l’IP du serveur et d’ajouter le port «9001» pour Plex et «9002» pour PlexPi. Pas très pratique de se rappeler des ports et surtout qu’on peux faire mieux facilement…

Traefik va nous aider puisque c’est un reverse proxy qui va automatiser les règles de routage des sous-domaines vers les bons containers en se connectant à l’API de Docker. Ainsi chaque nouveau container pourra être configuré avec un sous-domaine et surtout obtenir un certificat HTTPS pour chaque sous-domaine créé par Let’s encrypt.

Bien sur, il existe un container Docker !

Création du container Traefik

On va modifier le fichier docker-compose.yml que l’on a créé pour ajouter le nouveau container pour Traefik :

traefik:
 restart: always
 image: traefik
 container_name: traefik
 ports:
   - '80:80'
   - '443:443'
   - '8080:8080'
 labels:
   - 'traefik.enable=true'
   - 'traefik.port=8080'
   - 'traefik.frontend.rule=Host:traefik.domain.tld'
 volumes:
   - /var/run/docker.sock:/var/run/docker.sock
   - ./traefik:/etc/traefik

Il y a maintenant une nouvelle section labels qui contient des paramètres qui vont être utiles à Traefik pour savoir la configuration qu’il devra appliquer aux containers instancés, nous y reviendrons plus tard.

Configuration de Traefik

Néanmoins, ce n’est pas suffisant pour démarrer le container Traefik. La dernière ligne du bloc indique un montage du répertoire traefik, ce répertoire représente l’endroit ou l’on va stocker la configuration traefik.tml de Traefik.

defaultEntryPoints = ["http", "https", "ws", "wss"]

################################################################
# Web configuration backend
################################################################
[web]
address = ":8080"
[web.auth.basic]
# User: toto | Password: password
users = ["toto:$2y$05$zNs3wc5UPB4su8vbFugVPuKEaLJXMf5Z.9hAI1ulJpBbhbBprfppO"]

################################################################
# Entry-points configuration
################################################################
[entryPoints]
  [entryPoints.http]
    address = ":80"
    [entryPoints.http.redirect]
      entryPoint = "https"
  [entryPoints.https]
    address = ":443"
    [entryPoints.https.tls]

################################################################
# Docker configuration backend
################################################################
[docker]
domain = "example"
watch = true
exposedbydefault = false

################################################################
# Let's encrypt
################################################################
[acme]
email = "user@example.com"
storageFile = "/etc/traefik/acme.json"
onDemand = false
onHostRule = true
entryPoint = "https"

Voici quelques explications sur ce fichier qui est découpé en 4 sections :

Pour la partie Let’s encrypt n’oubliez pas qu’il y a des limitations sur le nombre de certificats que l’on peut demander. Pour éviter d’être black-listé par Let’s encrypt, je vous recommande de désactiver l’option onDemand, qui demanderai un nouveau certificat à chaque tentative de connexion à un sous-domaine.

Voila pour la configuration de Traefik.

Webapp d’administration

La webapp d’administration de Traefik est très simple, elle permet de rapidement visualiser les différentes règles de routing actives sur votre serveur. En gros, elle donne la liste des «frontends» et à quel «backend» il se connecte. Pour l’instant, il n’y a que le sous-domaine de Traefik dans la liste qui se connecte à son backend.

Interface de Traefik
Capture de l'interface de Traefik

C’est très pratique, lorsque l’on rencontre un petit soucis. Sécuriser ce domaine avec une authentification au minimum ou mieux en limitant l’accès à quelques IPs.

Configuration des containers

Revenons à nos moutons, c’est à dire avoir un reverse-proxy pour nos containers. Reprenons donc le fichier docker-compose.yml du précédent article, ou nous allons y ajouter le bloc de Traefik avec des labels :

Il n’y a que 4 lignes à ajouter par container dans le fichier et à adapter à vos besoins. Vous obtiendrez ainsi le fichier suivant :

version: '2'
services:

   traefik:
    restart: always
    image: traefik
    container_name: traefik
    ports:
      - '80:80'
      - '443:443'
      - '8080:8080'
    labels:
      - 'traefik.enable=true'
      - 'traefik.port=8080'
      - 'traefik.frontend.rule=Host:traefik.domain.tld'
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./traefik:/etc/traefik

 plex:
    image: linuxserver/plex
    container_name: plex
    environment:
      - VERSION=latest
      - PUID=1000
      - PGID=1000
      - TZ=Paris
    labels:
      - 'traefik.enable=true'
      - 'traefik.port=9001'
      - 'traefik.frontend.rule=Host:plex.domain.tld' 
    ports:
      - ’9001:32400'
    volumes:
      - 'plex:/config'
      - 'plex_transcode:/transcode'
      - '/home/johan/data:/data/'

  plexpy:
    image: linuxserver/plexpy
    container_name: plexpy
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Paris
    labels:
      - 'traefik.enable=true'
      - 'traefik.port=9002'
      - 'traefik.frontend.rule=Host:plexpy.domain.tld' 
    ports:
      - ‘9002:8181'
    volumes:
      - 'plexpy:/config'

volumes:
  plex:
    driver: local
  plex_transcode:
    driver: local
  plexpy:
    driver: local

Redémarrer tous vos containers avec les commandes :

docker-compose stop
docker-compose up -d 

Vous devriez maintenant être capable d’accèder à Plex via l’url https://plex.domain.tld et à PlexPy en accédant à https://plexpy.domain.tld.

Vous pourrez aussi voir la configuration de Traefik en visitant la webapp d’administration https://traefik.domain.tld :

Interface de Traefik
Capture de l'interface de Traefik avec les règles de routing

Résultat

Avec Traefik qui s’occupe de la configuration SSL des sous-domaines, il n’y a plus rien à faire pour obtenir une bonne note sur le service de SSL Labs de Qualys.

Interface de Traefik
Capture du résultat du test Qualys

Auparavant, je luttais pour péniblement obtenir un B+ sur le service, avec traefik le gain est là.

Conclusion

Traefik est donc un reverse-proxy qui correspond parfaitement à mon besoin, servir les différents services auto-hébergés en permettant avec très peu de configuration d’avoir une gestion automatisée des sous-domaines de mon serveur.

Je l’utilise sur la SheevaBoite depuis plusieurs mois et je n’ai rien à redire. Le projet est bien vivant, il évolue bien et la communauté est là et le service qu’il rend me fait gagner un temps de malade pour tester rapidement des services. Bien sur, Traefik ne se limite pas à faire du routing basique, il est complet puisqu’il peut faire du load-balancing avec gestion d’erreurs, mais cela ne rentre pas dans mon besoin. Je vous conseille de regarder du côté de la doc de Traefik.

Petit reproche tout de même, il ne gère pas encore le routing vers un service qui n’est pas hébergé sur Docker. Par exemple pour avoir une route vers mon NAS, mais je reviendrai sur ce point dans un prochain article, le soucis peut être facilement contourné…

Si vous voulez héberger vos services chez vous avec Docker, Traefik est vraiment l’outil que vous vous devez d’avoir.

Partager