Le jour où j'ai découvert Traefik
Été 2022. Je gérais une dizaine de conteneurs Docker sur mon infra personnelle. Portainer, Gitea, Paperless, mes applications Django, etc. Chaque fois que j'ajoutais un nouveau service, c'était la même routine : éditer la config Nginx, ajouter un bloc server, recharger Nginx, lancer Certbot pour le SSL, croiser les doigts. Ça prenait 15 minutes à chaque fois, et un jour, j'ai cassé la config Nginx. Tous mes services étaient down.
C'est là qu'un collègue m'a parlé de Traefik. "Tu ajoutes juste des labels Docker, et Traefik configure tout automatiquement, même le SSL." J'étais sceptique. Mais après l'avoir testé, je n'ai plus jamais touché à un fichier de conf Nginx pour mes conteneurs Docker. Traefik a changé ma vie de DevOps.
Pourquoi Traefik plutôt que Nginx pour Docker ?
Nginx, c'est le couteau suisse des reverse proxy. C'est puissant, rapide, éprouvé. Mais pour Docker, c'est l'enfer. Chaque fois que vous lancez un nouveau conteneur, vous devez éditer manuellement la config Nginx, relancer le service, gérer les certificats SSL. C'est répétitif, fastidieux, et source d'erreurs.
Traefik, c'est l'inverse. Il est conçu spécifiquement pour les environnements dynamiques comme Docker. Il écoute l'API Docker, détecte automatiquement les nouveaux conteneurs, lit leurs labels, et configure le routage tout seul. Vous lancez un conteneur avec les bons labels ? Boum, il est accessible via HTTPS avec un certificat Let's Encrypt généré automatiquement. Zéro config manuelle.
1. Architecture de Traefik
Traefik fonctionne en trois couches. D'abord, les entrypoints : ce sont les ports d'entrée (80 pour HTTP, 443 pour HTTPS). Ensuite, les routers : ils définissent les règles de routage (quelle URL va vers quel service). Enfin, les services : ce sont vos conteneurs Docker finaux.
Le plus beau, c'est que vous n'avez pas à configurer tout ça à la main. Traefik lit les labels Docker et génère automatiquement les routers et services. C'est de la découverte de services à la volée. Et avec les middlewares, vous pouvez ajouter des redirections HTTP vers HTTPS, de l'authentification basique, du rate limiting, etc.
2. Configuration avec docker-compose
Voici ma stack Traefik de base, celle que j'utilise sur tous mes serveurs. Elle gère le SSL automatique via Let's Encrypt, expose les ports 80 et 443, et est connectée au réseau Docker pour découvrir les conteneurs.
# docker-compose.yml pour Traefik
version: '3.8'
services:
traefik:
image: traefik:v2.11
container_name: traefik
restart: unless-stopped
security_opt:
- no-new-privileges:true
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./traefik.yml:/traefik.yml:ro
- ./acme.json:/acme.json
- ./logs:/logs
networks:
- web
labels:
# Dashboard Traefik (optionnel, sécurisé)
- "traefik.enable=true"
- "traefik.http.routers.dashboard.rule=Host(`traefik.mondomaine.fr`)"
- "traefik.http.routers.dashboard.service=api@internal"
- "traefik.http.routers.dashboard.entrypoints=https"
- "traefik.http.routers.dashboard.tls.certresolver=letsencrypt"
networks:
web:
external: true
Configuration traefik.yml
# traefik.yml
api:
dashboard: true
entryPoints:
http:
address: ":80"
http:
redirections:
entryPoint:
to: https
scheme: https
https:
address: ":443"
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false
network: web
certificatesResolvers:
letsencrypt:
acme:
email: contact@mondomaine.fr
storage: acme.json
httpChallenge:
entryPoint: http
log:
level: INFO
filePath: /logs/traefik.log
accessLog:
filePath: /logs/access.log
acme.json doit avoir les permissions 600 sinon Traefik refusera de démarrer. Faites touch acme.json && chmod 600 acme.json avant de lancer Traefik.3. Configuration des labels Docker
Maintenant, la magie. Pour exposer un conteneur via Traefik, vous ajoutez simplement des labels dans votre docker-compose.yml. Traefik détecte le conteneur, lit les labels, et configure tout automatiquement. Voici un exemple concret avec une application web.
# docker-compose.yml pour une application
version: '3.8'
services:
webapp:
image: monapp:latest
container_name: webapp
restart: unless-stopped
networks:
- web
labels:
- "traefik.enable=true"
- "traefik.http.routers.webapp.rule=Host(`app.mondomaine.fr`)"
- "traefik.http.routers.webapp.entrypoints=https"
- "traefik.http.routers.webapp.tls.certresolver=letsencrypt"
- "traefik.http.services.webapp.loadbalancer.server.port=8000"
networks:
web:
external: true
Explication des labels
traefik.enable=true: Active Traefik pour ce conteneur (obligatoire carexposedByDefault: false)traefik.http.routers.webapp.rule=Host(`app.mondomaine.fr`): Route tout le trafic venant deapp.mondomaine.frvers ce conteneurtraefik.http.routers.webapp.entrypoints=https: Utilise l'entrypoint HTTPS (port 443)traefik.http.routers.webapp.tls.certresolver=letsencrypt: Génère un certificat SSL via Let's Encrypt automatiquementtraefik.http.services.webapp.loadbalancer.server.port=8000: Le conteneur écoute sur le port 8000
C'est tout. Vous lancez le conteneur avec docker-compose up -d, et en 30 secondes, votre application est accessible en HTTPS avec un certificat valide. Pas de config Nginx, pas de Certbot, pas de rechargement de service. C'est automatique.
4. Let's Encrypt automatique
Le gros avantage de Traefik, c'est le SSL automatique. Avec Nginx, vous devez lancer Certbot manuellement, configurer le renouvellement automatique, gérer les certificats. Avec Traefik, vous spécifiez juste tls.certresolver=letsencrypt dans les labels, et Traefik s'occupe de tout.
Traefik génère le certificat lors du premier accès au domaine. Il le stocke dans acme.json. Et il le renouvelle automatiquement avant expiration. Vous n'avez littéralement rien à faire. J'ai des dizaines de domaines gérés par Traefik, et je n'ai jamais eu à toucher aux certificats manuellement. Ça marche, point.
5. Middleware : Redirections et sécurité
Les middlewares Traefik permettent de modifier les requêtes et réponses. Vous pouvez forcer HTTPS, ajouter de l'authentification basique, configurer du rate limiting, gérer les CORS, etc. Voici quelques exemples pratiques que j'utilise régulièrement.
Redirection HTTP vers HTTPS
Cette redirection est déjà configurée au niveau de l'entrypoint HTTP dans traefik.yml. Toutes les requêtes HTTP sont automatiquement redirigées vers HTTPS. Simple et efficace.
Authentification basique
# Ajouter un middleware d'auth basique
labels:
- "traefik.http.middlewares.auth.basicauth.users=admin:$$apr1$$xyz..."
- "traefik.http.routers.webapp.middlewares=auth"
# Générer le mot de passe hashé
htpasswd -nb admin motdepasse
Headers de sécurité
labels:
- "traefik.http.middlewares.security.headers.sslredirect=true"
- "traefik.http.middlewares.security.headers.stsSeconds=31536000"
- "traefik.http.middlewares.security.headers.contentTypeNosniff=true"
- "traefik.http.middlewares.security.headers.browserXssFilter=true"
- "traefik.http.routers.webapp.middlewares=security"
6. Cas d'usage pratiques
Plusieurs conteneurs, même domaine, différents chemins
# API sur /api, frontend sur /
labels:
# API
- "traefik.http.routers.api.rule=Host(`monsite.fr`) && PathPrefix(`/api`)"
- "traefik.http.routers.api.entrypoints=https"
- "traefik.http.services.api.loadbalancer.server.port=8000"
# Frontend
- "traefik.http.routers.frontend.rule=Host(`monsite.fr`)"
- "traefik.http.routers.frontend.entrypoints=https"
- "traefik.http.services.frontend.loadbalancer.server.port=3000"
Wildcard SSL (*.mondomaine.fr)
Pour un wildcard SSL, vous devez utiliser le DNS challenge au lieu du HTTP challenge. Cela nécessite une configuration DNS chez votre registrar, mais Traefik gère toute la complexité.
7. Traefik vs Nginx : Quand utiliser quoi ?
Soyons clairs : Nginx reste incontournable pour certains cas. Pour servir des fichiers statiques à haute performance, Nginx est imbattable. Pour des configurations complexes avec du caching avancé, du rate limiting granulaire, ou du load balancing custom, Nginx offre plus de contrôle. Et si vous n'utilisez pas Docker, Nginx est probablement plus simple.
Mais pour une infrastructure Docker, Traefik gagne haut la main. La découverte automatique des services, le SSL Let's Encrypt intégré, et la configuration par labels Docker rendent Traefik imbattable pour ce cas d'usage. Je peux déployer un nouveau service en 2 minutes au lieu de 15. Et je n'ai plus jamais cassé ma config de reverse proxy depuis que j'utilise Traefik.
Ma recommandation
Utilisez Traefik pour vos infrastructures Docker. C'est fait pour ça, et ça vous fera gagner un temps fou. Gardez Nginx pour les services non-Dockerisés, les sites statiques haute performance, ou les configurations très spécifiques. Et si vous avez déjà une stack Nginx qui marche bien, pas besoin de tout migrer. Mais pour un nouveau projet Docker, partez directement sur Traefik.
Pour aller plus loin : le cours vidéo et les réglages d'expert
Depuis l'écriture de cet article, j'ai enregistré un cours complet sur Traefik, dans lequel j'y branche Portainer, Uptime Kuma et Beszel, puis je passe aux réglages avancés. Si vous préférez apprendre en regardant, c'est par ici. La suite de cette section reprend les points du cours qui n'étaient pas encore couverts plus haut.
Et si la notion même de reverse proxy n'est pas encore claire, ce format court la résume en une minute :
Configuration statique et configuration dynamique
C'est la distinction qui m'a le plus aidé à comprendre les erreurs de Traefik :
- La configuration statique est lue une seule fois, au démarrage : les entrypoints, la connexion à Docker (le provider), les résolveurs de certificats. Pour la modifier, il faut redémarrer Traefik.
- La configuration dynamique contient les routers, services et middlewares. Elle vient des labels Docker (ou de fichiers surveillés) et se recharge à chaud, sans coupure.
Si vous ajoutez un label entrypoints qui n'existe pas dans la configuration statique, le router ne sera jamais actif : c'est une erreur classique.
Pourquoi exposedByDefault: false est si important
Je l'ai mis dans la configuration plus haut sans trop insister, mais c'est la ligne la plus importante. Avec cette option, seuls les conteneurs portant traefik.enable=true sont publiés. Sans elle, le moindre conteneur lancé sur la machine (une base de données de test, un outil interne) obtient automatiquement une route publique.
Les agents ne passent pas par Traefik
Une confusion fréquente quand on publie Portainer et Beszel : seules leurs interfaces web passent par Traefik. L'agent Portainer (port 9001) et l'agent Beszel (port 45876) sont des connexions de machine à machine, sur leurs propres ports. Chez moi, ils n'écoutent que sur l'interface WireGuard, et Traefik n'a rien à voir avec eux.
Le tableau de bord, protégé
Le dashboard de Traefik affiche tous les routers, services et middlewares détectés, avec leurs erreurs. C'est le premier endroit où regarder quand une route ne répond pas. Mais il ne doit jamais être exposé sans protection : il révèle toute la cartographie de vos services.
labels:
- traefik.http.routers.dashboard.rule=Host(`traefik.mondomaine.fr`)
- traefik.http.routers.dashboard.service=api@internal
- traefik.http.routers.dashboard.entrypoints=websecure
- traefik.http.routers.dashboard.tls.certresolver=letsencrypt
- traefik.http.routers.dashboard.middlewares=admin-auth,vpn-only
- traefik.http.middlewares.vpn-only.ipallowlist.sourcerange=10.8.0.0/24
Une vraie authentification unique avec forward auth
Le basic auth dépanne, mais pour protéger proprement plusieurs interfaces d'administration (Portainer, Beszel, Uptime Kuma), le middleware forwardAuth délègue la décision à un service d'authentification comme Authelia ou Authentik : une seule connexion, avec double authentification, pour toutes les applications.
labels:
- traefik.http.middlewares.sso.forwardauth.address=http://authelia:9091/api/authz/forward-auth
- traefik.http.middlewares.sso.forwardauth.trustForwardHeader=true
- traefik.http.middlewares.sso.forwardauth.authResponseHeaders=Remote-User,Remote-Groups
Il suffit ensuite d'ajouter sso@docker à la liste des middlewares de chaque router à protéger.
Répartition de charge et routage TCP
Lancez plusieurs réplicas d'un même service (docker compose up --scale web=3), et Traefik répartit automatiquement les requêtes entre eux. Avec un health check sur le service, il retire de la rotation les conteneurs qui ne répondent plus.
Traefik ne se limite pas au HTTP : il route aussi du TCP en lisant le nom de domaine transmis dans la négociation TLS (le SNI). On peut ainsi exposer plusieurs bases de données sur le même port 443, chacune sur son propre nom de domaine.
Observer Traefik
Traefik expose des métriques pour Prometheus, écrit des journaux d'accès au format JSON (utiles pour fail2ban ou une analyse ultérieure), et je fais surveiller chaque adresse publiée par Uptime Kuma, avec une alerte sur la date d'expiration du certificat. Si un renouvellement Let's Encrypt échoue en silence, je le sais des jours à l'avance.
Les bonnes pratiques, en résumé
exposedByDefault: false.- Le socket Docker en lecture seule, ou mieux, derrière un proxy de socket (
tecnativa/docker-socket-proxy) qui n'autorise que les appels nécessaires. - Le tableau de bord protégé, jamais public.
- Une redirection globale HTTP vers HTTPS sur l'entrypoint
web. - Une version d'image fixée (
traefik:v3.x), jamaislatest.
Ce qu'il faut retenir
Traefik révolutionne la gestion des reverse proxy dans les environnements Docker. Plus besoin de configurer manuellement Nginx, plus besoin de lancer Certbot à chaque nouveau service. Vous lancez un conteneur avec les bons labels, et Traefik configure tout automatiquement : routage, SSL, redirections.
Depuis que j'utilise Traefik, je ne perds plus de temps à éditer des fichiers de config. J'ajoute des labels Docker, et ça roule. Mon infrastructure est plus réactive, plus maintenable, et franchement plus agréable à gérer. Si vous bossez avec Docker et que vous n'avez pas encore testé Traefik, vous passez à côté d'un outil qui va vraiment améliorer votre quotidien.