Traefik v3 : reverse proxy dynamique et découverte de services pour une stack Docker
Nginx est un reverse proxy éprouvé, mais dans une stack Docker multi-conteneurs qui évolue souvent, sa configuration statique devient vite fastidieuse : chaque nouveau service nécessite de modifier un fichier, de recharger le démon, de gérer manuellement les certificats TLS. Traefik adopte une philosophie inverse : il observe les labels des conteneurs Docker pour configurer ses routes dynamiquement, renouvelle les certificats Let’s Encrypt automatiquement, et expose un tableau de bord en temps réel. Traefik v3, sorti en 2024, apporte des améliorations significatives pour les environnements Kubernetes et Docker modernes.
Pourquoi Traefik plutôt que Nginx dans une stack auto-hébergée ?
La différence fondamentale est le modèle de configuration. Nginx est un fichier statique qu’on recharge, donc chaque changement nécessite une intervention. Traefik interroge en continu le socket Docker (ou l’API Kubernetes) et reconfigure ses routes à chaud dès qu’un conteneur démarre ou s’arrête. Dans une infrastructure composée d’une dizaine de services (CKAN, Keycloak, Nextcloud, Superset, Gitea, MinIO…), cela change la maintenance en profondeur.
L’autre avantage décisif est la gestion TLS native. Traefik intègre le client ACME (Let’s Encrypt / ZeroSSL) et renouvelle les certificats de chaque service automatiquement, sans cron, sans certbot externe. Il supporte les challenges HTTP-01 et DNS-01, ce qui permet de certifier des services non exposés publiquement en utilisant l’API DNS.
En contrepartie, Nginx reste plus adapté pour les configurations très spécifiques (réécriture complexe d’URL, cache de proxy, gestion fine des headers HTTP) et offre de meilleures performances brutes en tant que serveur de fichiers statiques. Les deux outils ne sont pas exclusifs, une architecture courante place Traefik devant pour la terminaison TLS et la distribution vers les services, avec Nginx utilisé à l’intérieur de certains services pour leurs besoins propres.
Architecture de Traefik v3
Traefik s’articule autour de trois concepts centraux. Les entrypoints sont les ports d’écoute déclarés dans la configuration statique (port 80 HTTP, 443 HTTPS, 8080 dashboard). Les routers définissent les règles de correspondance entre une requête entrante et un service backend, typiquement basées sur le hostname ou le chemin URL. Les services désignent les groupes de conteneurs qui traitent les requêtes, avec équilibrage de charge intégré. Entre les routers et les services, des middlewares permettent d’appliquer des transformations : redirection HTTPS, authentification basique, rate limiting, ajout de headers de sécurité.
Avec Docker, toute cette configuration se déclare par des labels sur les conteneurs, sans toucher au fichier de configuration central de Traefik. C’est l’inversion de contrôle : c’est le service qui se déclare auprès du proxy, et non l’administrateur qui configure le proxy pour chaque service.
Déploiement avec Docker Compose
La configuration statique de Traefik est minimale. On crée un fichier traefik.yml et un docker-compose.yml :
# traefik.yml — configuration statique
api:
dashboard: true
insecure: false
entryPoints:
web:
address: ":80"
http:
redirections:
entryPoint:
to: websecure
scheme: https
websecure:
address: ":443"
providers:
docker:
exposedByDefault: false
network: traefik-public
certificatesResolvers:
letsencrypt:
acme:
email: admin@example.com
storage: /letsencrypt/acme.json
httpChallenge:
entryPoint: web
# docker-compose.yml — Traefik v3
services:
traefik:
image: traefik:v3
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./traefik.yml:/traefik.yml:ro
- traefik-certs:/letsencrypt
networks:
- traefik-public
labels:
- "traefik.enable=true"
- "traefik.http.routers.dashboard.rule=Host(`traefik.example.com`)"
- "traefik.http.routers.dashboard.entrypoints=websecure"
- "traefik.http.routers.dashboard.tls.certresolver=letsencrypt"
- "traefik.http.routers.dashboard.service=api@internal"
- "traefik.http.routers.dashboard.middlewares=auth"
- "traefik.http.middlewares.auth.basicauth.users=admin:$$apr1$$..."
networks:
traefik-public:
external: true
volumes:
traefik-certs:
Exposer un service derrière Traefik
Pour qu’un service soit automatiquement pris en charge par Traefik, il suffit de lui ajouter les bons labels dans son propre docker-compose.yml. Exemple avec CKAN :
services:
ckan:
image: ckan/ckan-base:2.10
networks:
- traefik-public
- internal
labels:
- "traefik.enable=true"
- "traefik.http.routers.ckan.rule=Host(`data.example.com`)"
- "traefik.http.routers.ckan.entrypoints=websecure"
- "traefik.http.routers.ckan.tls.certresolver=letsencrypt"
- "traefik.http.services.ckan.loadbalancer.server.port=5000"
networks:
traefik-public:
external: true
internal:
Traefik détecte ce conteneur au démarrage, crée le routeur, obtient le certificat TLS pour data.example.com, et commence à router le trafic, sans toucher à la configuration centrale et sans recharger quoi que ce soit.
Middlewares essentiels en production
Les middlewares sont appliqués dans la chaîne entre le routeur et le service. Quelques exemples utiles en production :
Headers de sécurité — Ajouter automatiquement les en-têtes HSTS, Content-Security-Policy et X-Frame-Options à toutes les réponses d’un service :
- "traefik.http.middlewares.secure-headers.headers.stsSeconds=31536000"
- "traefik.http.middlewares.secure-headers.headers.stsIncludeSubdomains=true"
- "traefik.http.middlewares.secure-headers.headers.frameDeny=true"
- "traefik.http.middlewares.secure-headers.headers.contentTypeNosniff=true"
Rate limiting : Limiter le nombre de requêtes par IP pour protéger une API ou un formulaire de connexion :
- "traefik.http.middlewares.ratelimit.ratelimit.average=100"
- "traefik.http.middlewares.ratelimit.ratelimit.burst=50"
Forward Auth : Déléguer l’authentification à un service externe, typiquement Keycloak ou Authelia, avant de laisser passer la requête vers le service final :
- "traefik.http.middlewares.keycloak-auth.forwardauth.address=https://auth.example.com/verify"
- "traefik.http.middlewares.keycloak-auth.forwardauth.trustForwardHeader=true"
Nouveautés de Traefik v3
Traefik v3 (disponible depuis avril 2024) introduit plusieurs changements importants. Le support natif de HTTP/3 (QUIC) est activable par entrypoint. La syntaxe des règles de routage gagne un opérateur && pour combiner des conditions sur le hostname et le chemin. Le support des plugins WASM permet d’écrire des middlewares personnalisés dans n’importe quel langage compilable en WebAssembly, sans fork du binaire. Côté Kubernetes, le provider CRD est stabilisé avec un support amélioré des IngressRoutes TCP et UDP.
La migration depuis v2 est documentée et généralement sans friction pour les configurations Docker, les labels restent identiques. Les changements notables concernent principalement la gestion des plugins et quelques renommages dans la configuration statique.
Traefik dans une architecture complète
Dans une stack auto-hébergée typique, Traefik occupe la position de point d’entrée unique : un seul conteneur écoute sur les ports 80 et 443, distribue le trafic vers CKAN, Keycloak, Nextcloud, Superset, Gitea et MinIO en fonction du hostname. Chaque service dispose de son propre certificat TLS généré automatiquement. Le tableau de bord Traefik (lui-même protégé par Basic Auth ou ForwardAuth) donne une vue en temps réel des routes actives, de l’état des certificats, et des erreurs éventuelles.
Cette architecture centralise la sécurité (TLS, headers, rate limiting) au niveau du proxy tout en laissant à chaque équipe ou service la responsabilité de déclarer ses propres labels, une répartition des responsabilités cohérente avec les principes DevOps modernes.
