Vous nous avez demandé un tutoriel sur comment mettre une configuration en place afin de rediriger les requêtes vers les bons containers en utilisant Traefik. L’utilisation de Traefik se déroulant presque exclusivement par des fichiers de configuration, j’ai préféré vous en parler via quelques exemples courants:

Exemple de configuration Traefik (traefik/docker-compose.yml)

Voici un fichier docker-compose.yml qui montera le container de Traefik. Les explications sont situées ci-dessous.

docker-compose.yaml
version: "3.3"
networks:
web:
services:
traefik:
image: traefik:v2.2
restart: always
container_name: traefik
ports: - "80:80" - "443:443" # - "8080:8080"
command:
- --api.insecure=true
- --api.dashboard=true
- --api.debug=true
- --log.level=DEBUG
- --providers.docker=true
- --providers.docker.exposedbydefault=false
- --providers.docker.network=traefik_web
# - --providers.file.filename=/dynamic.yaml
- --entrypoints.http.address=:80
- --entrypoints.https.address=:443
- --certificatesresolvers.tls.acme.tlschallenge=true
- --certificatesresolvers.tls.acme.email=contact@mon-domaine.com
- --certificatesresolvers.tls.acme.storage=/letsencrypt/acme.json
volumes:
- ./letsencrypt:/letsencrypt
- /var/run/docker.sock:/var/run/docker.sock
# - ./dynamic.yaml:/dynamic.yaml
networks:
- web
labels:
- "traefik.enable=true"
- "traefik.http.middlewares.http_to_https.redirectscheme.scheme=https"
- "traefik.http.middlewares.auth.basicauth.users=test:$$2y$$12$$iPbYdyAEZbyTYjEEU5Bneu/GKrciqcwYtZqZJwUxHsjgfrRXrBEEW"
- "traefik.http.routers.monitor.rule=Host(`monitor.mon-domaine.com`)"
- "traefik.http.routers.monitor.entrypoints=http"
- "traefik.http.routers.monitor.middlewares=http_to_https@docker"
- "traefik.http.routers.monitor-secured.rule=Host(`monitor.mon-domaine.com`)"
- "traefik.http.routers.monitor-secured.service=api@internal"
- "traefik.http.routers.monitor-secured.entrypoints=https"
- "traefik.http.routers.monitor-secured.tls.certresolver=tls"
- "traefik.http.routers.monitor-secured.middlewares=auth@docker"
environment:
- "OVH_ENDPOINT=ovh-eu"
- "OVH_APPLICATION_KEY=XXXXXXXXXXXXXXXX"
- "OVH_APPLICATION_SECRET=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
- "OVH_CONSUMER_KEY=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"

Explication

Ce docker-compose va en premier lieu télécharger l’image traefik:v2.2 via le docker hub. Traefik prendra toutes les requêtes entrantes sur le port 80 et 443.

La configuration est scindées en deux parties, la partie command et la partie labels.

Les commandes

La première partie commande sert à l’initialisation des variables de Traefik.

En tout premier lieu nous créons un réseau nommé traefik_web.

networks:
web:

Attention: ici, le réseau s’appelle traefik_web car nous supposons que le fichier docker-compose.yml se situe dans un dossier nommé traefik². Docker va automatiquement concaténer le nom du dossier avec le nom du réseau.

Ici, nous allons mettre en place l’API web de docker. Cette API nous donnera des informations à propos de l’état de docker:

- --api.insecure=true
- --api.dashboard=true
- --api.debug=true
- --log.level=DEBUG

Ici, nous allons placer docker dans un réseau s’appelant traefik_web:

- --providers.docker=true
- --providers.docker.exposedbydefault=false
- --providers.docker.network=traefik_web

Si vous voulez ajouter un fichier de configuration dynamique, vous pouvez l’ajouter en décommentant cette ligne:

# - --providers.file.filename=/dynamic.yaml

Nous définissions deux entrypoints:

  • Un entrypoint nommé “http”, écoutant sur le port 80.
  • Un entrypoint nommé “https”, écoutant sur le port 443.

80 et 443 sont les ports par défaut des requêtes sur le web.

- --entrypoints.http.address=:80
- --entrypoints.https.address=:443

Enfin, nous créons un “certificatesresolver” nommé “tls”, et qui générera un certificat SSL automatiquement:

- --certificatesresolvers.tls.acme.tlschallenge=true
- --certificatesresolvers.tls.acme.email=contact@mon-domaine.com
- --certificatesresolvers.tls.acme.storage=/letsencrypt/acme.json

Pour l’instant, rien de très sorcier.

Les labels

Les labels servent à configurer l’application. Ils se servent des variables de traefik déclarés plus haut.

Ici, nous allons mettre en place l’API web de Traefik, afin d’avoir des informations sur le container en temps réel.

Pour activer Traefik, vous devez écrire cette ligne.

- "traefik.enable=true"

Ici, nous allons créer un “middleware”. Un middleware est une fonction qui va capturer la requête ou la réponse, et qui va la modifier selon des critères. Ici, nous créons un exemple de middleware nommé http_to_https. Comme son nom l’indique, ce middleware se chargera d’envoyer une entête au navigateur du client afin de le rediriger vers la version https du site:

- "traefik.http.middlewares.http_to_https.redirectscheme.scheme=https"

Ici, cet autre middleware nommé “auth” sert à créer une porte d’authentification. La longue chaine de caractère est le résultat de la commande htpasswd -nbBC 10 test test:

- "traefik.http.middlewares.auth.basicauth.users=test:$$2y$$12$$iPbYdyAEZbyTYjEEU5Bneu/GKrciqcwYtZqZJwUxHsjgfrRXrBEEW"

La commande donnée génère des identifiants qui ont pour nom “test” et mot de passe “test”.

Attention: il faut bien penser à doubler le caractère ”$” dans la chaine de caractère obtenue afin de pouvoir l’échapper

Voir la documentation

Une fois toutes les données mise en place, nous pouvons créer nos routes. Les routes sont les chemins que prendra le client pour accéder à notre application.

- "traefik.http.routers.monitor.rule=Host(`monitor.mon-domaine.com`)"
- "traefik.http.routers.monitor.entrypoints=http"
- "traefik.http.routers.monitor.middlewares=http_to_https@docker"

Ici, nous créons une route nommée “monitor”, avec des conditions:

  • il faut que le nom de domaine soit “monitor.mon-domaine.com”
  • il faut que le client passe par l’entrypoint nommé “http” (soit le port 80, comme déclaré dans la partie “commandes”)

La dernière ligne sert à, si le client arrive à passer ces conditions, de le rediriger vers la version “https” du site, grâce au middleware “http_to_https” déclaré ci-dessus.

Ici, nous allons voir la partie https du site:

- "traefik.http.routers.monitor-secured.rule=Host(`monitor.mon-domaine.com`)"
- "traefik.http.routers.monitor-secured.service=api@internal"
- "traefik.http.routers.monitor-secured.entrypoints=https"
- "traefik.http.routers.monitor-secured.tls.certresolver=tls"
- "traefik.http.routers.monitor-secured.middlewares=auth@docker"

Ici, nous créons une route nommée “monitor-secured”, écoutant sur l’entrypoint “https” (port 443) et vérifiant que le domaine “monitor.mon-domaine.com” soit bien utilisé. Traefik va devoir ici résoudre le certificat SSL via la fonction “tls”. Enfin, la méthode d’authentification “auth” va être utilisée (voir plus haut).

Un exemple de configuration de container (whoami/docker-compose.yml)

docker-compose.yaml
version: "3.3"
networks:
traefik_web:
external: true
services:
whoami:
image: "containous/whoami"
restart: always
networks:
- traefik_web
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami.rule=Host(`whoami.mon-domaine.com`)"
- "traefik.http.routers.whoami.entrypoints=http"
- "traefik.http.routers.whoami.middlewares=http_to_https@docker"
- "traefik.http.routers.whoami-secured.rule=Host(`whoami.mon-domaine.com`)"
- "traefik.http.routers.whoami-secured.entrypoints=https"
- "traefik.http.routers.whoami-secured.tls.certresolver=tls"
- "traefik.http.routers.whoami-secured.middlewares=auth@docker"

Pour configurer les conteneurs que l’on veut relier à Traefik, nous avons juste à utiliser les labels correspondant.

Le premier label traefik.enable=true sert uniquement à activer Traefik.

- "traefik.http.routers.whoami.rule=Host(`whoami.mon-domaine.com`)"
- "traefik.http.routers.whoami.entrypoints=http"
- "traefik.http.routers.whoami.middlewares=http_to_https@docker"

les trois suivant créent une route nommée whoami qui va tester si le nom d’hôte est bien whoami.mon-domaine.com et si la requête est lancée sur le port 80 (http). Puis nous relions le middleware http_to_https créé dans docker, qui va rediriger la connexion vers le port 443 (https).

- "traefik.http.routers.whoami-secured.rule=Host(`whoami.mon-domaine.com`)"
- "traefik.http.routers.whoami-secured.entrypoints=https"
- "traefik.http.routers.whoami-secured.tls.certresolver=tls"
- "traefik.http.routers.whoami-secured.middlewares=auth@docker"

Enfin pour terminer, les quatre dernières lignes vont créer une route nommée whoami-secured qui va tester si le nom d’hôte est bien whoami.mon-domaine.com et si la requête est lancée sur le port 443 (https). Dans ce cas ci, nous allons demander à Traefik d’envoyer le certificat SSL via la fonction tls crée précédemment. La dernière ligne va appeler le middleware auth, qui va demander un identifiant et un mot de passe à l’utilisateur (ici les pseudo et mot de passe sont “test” et “test”).

Un exemple nécessitant un container non accessible publiquement

Dans cette dernière partie, nous voyons un cas de figure fréquent : comment “cacher” un container qu’il ne soit pas accessible publiquement.

Ici, nous allons voir avec l’exemple de Nextcloud, mais cela fonctionne avec Wordpress ou toute autre image également !

docker-compose.yaml
version: "3.3"
networks:
traefik_web:
external: true
backend:
external: false
services:
db:
image: mariadb
command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW
restart: always
volumes:
- ./db:/var/lib/mysql
networks:
- backend
environment:
- MYSQL_ROOT_PASSWORD=password_root
- MYSQL_PASSWORD=password
- MYSQL_DATABASE=nextcloud
- MYSQL_USER=nextcloud
app:
image: nextcloud
restart: always
volumes:
- ./nextcloud:/var/www/html
networks:
- traefik_web - backend
labels:
- "traefik.enable=true"
- "traefik.http.routers.cloud.rule=Host(`cloud.mon-domaine.com`)"
- "traefik.http.routers.cloud.entrypoints=http"
- "traefik.http.routers.cloud-secured.rule=Host(`cloud.mon-domaine.com`)"
- "traefik.http.routers.cloud-secured.entrypoints=https"
- "traefik.http.routers.cloud-secured.tls.certresolver=tls"
- "traefik.http.routers.cloud.middlewares=http_to_https@docker"

Pour l’explication, l’astuce va être de créer un network nommé backend.

backend:
external: false

Ce réseau va être utilisé par les deux containers, et ne sera pas accessible publiquement !

En savoir plus


Articles recommandés