Traefik

Traefik est un reverse proxy et un load-balancer conçu pour déployer des microservices fournis par des conteneurs. L’avantage de traefik est qu’il va inclure dynamiquement les nouveaux conteneurs qui sont montés.

Considérons le cas d’usage où le domaine monsite.fr publie deux services :

  • un blog accessible à l’adresse blog.monsite.fr (et son alias www.monsite.fr)
  • une plateforme shiny à l’adresse shiny.monsite.fr

alt text

La configuration est effectuée dans un fichier docker-compose.yml hormis la configuration “classique” figure des labels qui permettront de définir des options à chacun des conteneurs.

La logique est d’avoir un point d’entrée le frontend sur lequel on applique une frontend rule :

traefik.frontend.rule=Host:monsite.fr,blog.monsite.fr

qui renvoie sur son backend en http sur le port 1080

"traefik.entryPoint=http"
"traefik.port=1080"
"traefik.backend=blog"

Configuration complète

docker-compose

version: '3.2'

services:

    traefik:

        image: traefik:1.7.16
        restart: unless-stopped
        ports:
            - "80:80"
            - "443:443"
        volumes:
            # Traefik se branche sur la socket de docker pour être notifié 
            # à la création et à la destruction des conteneurs
            - /var/run/docker.sock:/var/run/docker.sock 
            - ./mount/conf/traefik.toml:/traefik.toml
            # Stockage du résultats des challenges de letsencrypt
            - ./mount/conf/acme/acme.json:/acme.json
            - ./mount/log:/log
        labels:
            - "traefik.enable=true"
            # Traefik va appliquer le proxy sur sa propre GUI
            - "traefik.port=8080"
            - "traefik.entryPoint=https"
            - "traefik.backend=dashboard"
            - "traefik.frontend.rule=Host:dashboard.monsite.fr"
            # L'accès au dashboard sera limité à ces deux ips
            - "traefik.frontend.whiteList.sourceRange=212.5.71.24,1.2.3.4"
        networks:
            - traefik_network
    shiny:
        container_name: shiny
        image: rocker/shiny
        restart: unless-stopped
        user: 'shiny'
        environment:
         - APPLICATION_LOGS_TO_STDOUT=false
        volumes:
         - "/opt/docker/shiny/mount/logs:/var/log/shiny-server"
        labels:
         - "traefik.enable=true"
         - "traefik.entryPoint=http"
         - "traefik.port=3838"
         - "traefik.backend=shiny"
         - "traefik.frontend.rule=Host:shiny.monsite.fr"
        networks:
         - traefik_network
    hugo:
      environment:
              - BASEURL=http://monsite.fr
              - BIND_PORT=1080
      image: daki/hugo
      container_name: hugo
      restart: unless-stopped
      hostname: hugo
      volumes:
        - /opt/docker/hugo/mount:/var/www
      labels:
	  # Le traffic a destination de blog.monsite.fr et www.monsite.fr
          # sera redirigé sur ce conteneur vers le port 1080
        - "traefik.enable=true"
        - "traefik.entryPoint=http"
        - "traefik.port=1080"
        - "traefik.backend=blog"
        - "traefik.frontend.rule=Host:monsite.fr,blog.monsite.fr"
        - "traefik.frontend.headers.forceSTSHeader=true"
        - "traefik.frontend.headers.STSSeconds=315360000"
        - "traefik.frontend.headers.STSIncludeSubdomains=true"
        - "traefik.frontend.headers.STSPreload=true"
      networks:
         - traefik_network
networks:
    traefik_network:
        external: true

Créer un fichier vide acme.json et lui donner les droits 600

touch ./mount/conf/acme/acme.json
chmod 600

traefik.toml

##
defaultEntryPoints = ["https", "http"]
[traefikLog]
filePath = "/log/traefik.log"
#format   = "json"
[entryPoints]
  [entryPoints.http]
  address = ":80"
  # On force la redirection en https
  [entryPoints.http.redirect]
      entryPoint = "https"
  ##
  [entryPoints.https]
  address = ":443"
   [entryPoints.https.tls]
     minVersion = "VersionTLS12"
     cipherSuites = [
      "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
      "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", 
      "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305"
     ]
[docker]
endpoint = "unix:///var/run/docker.sock"
# Nom de domaine par défaut pour les conteneurs
domain = "monsite.fr"
watch = true
# Cette directive définit si traefik doit de manière automatique 
# crééer le routage à chaque fois qu'un nouveau conteneur est créé
exposedByDefault = false
##
[web]
  address = ":8080"
  # Mise en place d'une authentication basic pour l'accès au dashboard
  [web.auth.basic]
  users = ["admin:$apr1$bFhdoJ2K$rM8Oxwy8fYfIJZfuL4iSpp"]
  ##
# Configuration letsencrypt
[acme]
email = "contact@monsite.fr"
storage = "/acme.json"
caServer = "https://acme-v02.api.letsencrypt.org/directory"
entryPoint = "https"
onHostRule = true
 [acme.httpChallenge]
   entryPoint = "http"

Avec la configuration ci-dessus les certificats des différents domaines (shiny.monsite.fr ; blog.monsite.fr ; dashboard.monsite.fr) sont générés dynamiquement.

alt text

Related