
Traefik détecte automatiquement vos conteneurs Docker et crée les routes correspondantes sans fichier de configuration à maintenir. Vous définissez le routage directement via des labels sur vos conteneurs : Traefik lit ces labels, génère la configuration et l'applique en temps réel.
Ce guide vous montre comment configurer le provider Docker, écrire les labels de routage, gérer les réseaux, et déployer des applications complètes avec Docker Compose. À la fin, vous saurez exposer n'importe quel conteneur en quelques secondes.
Comment fonctionne le provider Docker
Section intitulée « Comment fonctionne le provider Docker »Le provider Docker remplace le fichier de configuration dynamique : Traefik interroge le daemon, lit les labels portés par chaque conteneur et en déduit les routers, services et middlewares correspondants. La configuration de routage vit donc à côté de l'application qu'elle expose, dans le même docker-compose.yml. Cette partie détaille les trois éléments du mécanisme : la découverte, l'accès au socket Docker et la grammaire des labels.
Découverte automatique
Section intitulée « Découverte automatique »Quand le provider Docker est activé, Traefik :
- Se connecte au daemon Docker via le socket Unix
- Surveille les événements (création, suppression, modification de conteneurs)
- Lit les labels de chaque conteneur
- Génère la configuration de routage correspondante
- Applique immédiatement les changements (hot-reload)
Communication via le socket Docker
Section intitulée « Communication via le socket Docker »Traefik communique avec Docker via le socket Unix (/var/run/docker.sock). Ce socket donne accès à toute l'API Docker, ce qui pose un risque de sécurité.
Labels comme configuration dynamique
Section intitulée « Labels comme configuration dynamique »Les labels Docker sont des métadonnées clé-valeur attachées aux conteneurs. Traefik les utilise pour configurer :
- Les routers : règles de routage (Host, Path...)
- Les services : port du conteneur, load balancing
- Les middlewares : authentification, headers, rate limiting
Configuration du provider Docker
Section intitulée « Configuration du provider Docker »Ces réglages appartiennent à la configuration statique, celle que Traefik lit une seule fois : toute modification impose un redémarrage du conteneur Traefik, contrairement aux labels pris en compte à chaud. Deux options structurent tout le reste, l'endpoint qui désigne le daemon à interroger et exposedByDefault qui décide du sort d'un conteneur sans label.
Configuration minimale
Section intitulée « Configuration minimale »Dans votre fichier traefik.yaml (configuration statique) :
providers: docker: endpoint: "unix:///var/run/docker.sock" exposedByDefault: false| Option | Description | Recommandation |
|---|---|---|
endpoint | Chemin du socket Docker | Toujours unix:///var/run/docker.sock sur Linux |
exposedByDefault | Expose automatiquement tous les conteneurs | false (sécurité) |
Options avancées
Section intitulée « Options avancées »network évite de répéter traefik.docker.network sur chaque conteneur, et constraints restreint les conteneurs considérés, ce qui permet de faire cohabiter plusieurs instances de Traefik sur un même hôte.
providers: docker: endpoint: "unix:///var/run/docker.sock" exposedByDefault: false network: traefik-public # Réseau par défaut watch: true # Surveiller les changements defaultRule: "Host(`{{ normalize .Name }}.example.com`)" # Règle par défaut constraints: "Label(`traefik.zone`, `public`)" # Filtrer les conteneurs| Option | Description |
|---|---|
network | Réseau Docker à utiliser pour la communication |
watch | Surveiller les événements Docker en temps réel |
defaultRule | Règle de routage par défaut (utilise les templates Go) |
constraints | Expression pour filtrer les conteneurs à considérer |
Exposer un conteneur simple
Section intitulée « Exposer un conteneur simple »L'exemple monte deux conteneurs sur un réseau commun : Traefik, qui écoute sur le port 80 et lit le socket, et whoami, qui renvoie les en-têtes de la requête reçue. Cette seconde image sert de sonde : la présence des en-têtes X-Forwarded-* dans sa réponse prouve que la requête est bien passée par le proxy, et non directement par le conteneur.
-
Créer le fichier docker-compose.yml
docker-compose.yml services:traefik:image: traefik:v3.7.6container_name: traefikrestart: unless-stoppedcommand:- "--api.dashboard=true"- "--api.insecure=true"- "--providers.docker=true"- "--providers.docker.exposedbydefault=false"- "--entrypoints.web.address=:80"ports:- "80:80"- "8080:8080"volumes:- /var/run/docker.sock:/var/run/docker.sock:ronetworks:- traefik-publicwhoami:image: traefik/whoami:v1.11.0container_name: whoamilabels:- "traefik.enable=true"- "traefik.http.routers.whoami.rule=Host(`whoami.localhost`)"- "traefik.http.routers.whoami.entrypoints=web"networks:- traefik-publicnetworks:traefik-public:name: traefik-public -
Lancer les conteneurs
Fenêtre de terminal docker compose up -d# Vérifier le statutdocker compose psRésultat attendu :
NAME IMAGE STATUS PORTStraefik traefik:v3.7.6 running 0.0.0.0:80->80/tcp, 0.0.0.0:8080->8080/tcpwhoami traefik/whoami running -
Tester le routage
Fenêtre de terminal # Tester avec le header Hostcurl -H "Host: whoami.localhost" http://localhostRésultat attendu :
Hostname: whoamiIP: 172.19.0.3RemoteAddr: 172.19.0.2:56842GET / HTTP/1.1Host: whoami.localhostUser-Agent: curl/8.5.0Accept: */*Accept-Encoding: gzipX-Forwarded-For: 172.19.0.1X-Forwarded-Host: whoami.localhostX-Forwarded-Port: 80X-Forwarded-Proto: httpX-Forwarded-Server: traefikX-Real-Ip: 172.19.0.1
Référence des labels Traefik
Section intitulée « Référence des labels Traefik »Tous les labels suivent le même schéma : traefik.<protocole>.<type>.<nom>.<option>. Le nom est libre et ne sert qu'à relier entre eux les labels d'un même router ou d'un même service ; deux conteneurs qui réutilisent le même nom entrent en conflit. Les sections ci-dessous couvrent le routage de base, le TLS, les middlewares et les entrées TCP/UDP.
Labels de base
Section intitulée « Labels de base »Le label traefik.enable conditionne tous les autres tant que exposedByDefault vaut false. Le port n'est à préciser que si le conteneur en expose plusieurs, ou aucun.
| Label | Description | Exemple |
|---|---|---|
traefik.enable | Activer l'exposition du conteneur | true ou false |
traefik.http.routers.<n>.rule | Règle de routage HTTP | Host('app.example.com') |
traefik.http.routers.<n>.entrypoints | Points d'entrée à utiliser | web,websecure |
traefik.http.routers.<n>.priority | Priorité du router (plus élevé = prioritaire) | 100 |
traefik.http.services.<n>.loadbalancer.server.port | Port du conteneur | 8080 |
Note : Remplacez <n> par le nom de votre router/service (ex: myapp, api, frontend).
Labels TLS
Section intitulée « Labels TLS »tls=true suffit à servir en HTTPS avec un certificat déjà chargé ; ajouter certresolver déclenche la demande automatique auprès de l'autorité déclarée dans la configuration statique. Les entrées domains[0] ne servent que pour un certificat wildcard ou multi-domaines.
labels: # Activer TLS - "traefik.http.routers.myapp.tls=true"
# Utiliser un certificat resolver (Let's Encrypt) - "traefik.http.routers.myapp.tls.certresolver=letsencrypt"
# Domaines pour le certificat - "traefik.http.routers.myapp.tls.domains[0].main=example.com" - "traefik.http.routers.myapp.tls.domains[0].sans=www.example.com,api.example.com"Labels middlewares
Section intitulée « Labels middlewares »Deux familles de labels cohabitent ici : ceux qui définissent un middleware et celui qui l'attache à un router. Un middleware défini mais jamais attaché reste sans effet, et l'ordre de la liste correspond à l'ordre d'exécution sur la requête.
labels: # Attacher un ou plusieurs middlewares - "traefik.http.routers.myapp.middlewares=auth,compress,headers"
# Définir un middleware BasicAuth - "traefik.http.middlewares.auth.basicauth.users=admin:$$apr1$$xxx"
# Définir un middleware Headers - "traefik.http.middlewares.headers.headers.stsSeconds=31536000" - "traefik.http.middlewares.headers.headers.contentTypeNosniff=true"
# Définir un RateLimit - "traefik.http.middlewares.ratelimit.ratelimit.average=100" - "traefik.http.middlewares.ratelimit.ratelimit.burst=50"Labels TCP/UDP
Section intitulée « Labels TCP/UDP »Pour les services TCP ou UDP (bases de données, DNS...) :
labels: - "traefik.tcp.routers.mysql.rule=HostSNI(`*`)" - "traefik.tcp.routers.mysql.entrypoints=mysql" - "traefik.tcp.services.mysql.loadbalancer.server.port=3306"Réseaux Docker
Section intitulée « Réseaux Docker »La communication entre Traefik et un conteneur passe par le réseau Docker, pas par les ports publiés sur l'hôte : un conteneur sans section ports: reste parfaitement joignable par le proxy. Encore faut-il que les deux partagent un réseau. C'est le rôle du réseau externe décrit ici, qui survit aux docker compose down et laisse la possibilité d'isoler les bases de données sur un second réseau privé.
Pourquoi utiliser un réseau dédié
Section intitulée « Pourquoi utiliser un réseau dédié »Par défaut, Docker crée un réseau bridge pour chaque projet Compose. Problème : Traefik ne peut pas atteindre les conteneurs d'autres projets.
Solution : Créer un réseau Docker externe partagé entre Traefik et tous les services à exposer.
┌─────────────────────────────────────────────────────────────────────────┐│ Réseau traefik-public ││ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ││ │ Traefik │ │ App A │ │ App B │ │ App C │ ││ │ │──│──────────│──│──────────│──│──────────│ ││ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │└─────────────────────────────────────────────────────────────────────────┘Configuration réseau
Section intitulée « Configuration réseau »Le réseau doit exister avant le premier docker compose up, d'où sa création manuelle. La mention external: true indique à Compose de le réutiliser au lieu d'en créer un nouveau préfixé par le nom du projet.
-
Créer le réseau externe :
Fenêtre de terminal docker network create traefik-public -
Référencer le réseau dans docker-compose.yml :
docker-compose.yml services:myapp:image: nginxnetworks:- traefik-public- internal # Réseau interne pour base de donnéesnetworks:traefik-public:external: trueinternal:driver: bridge
Multi-réseaux
Section intitulée « Multi-réseaux »Un conteneur peut appartenir à plusieurs réseaux. Utilisez cette technique pour séparer :
- traefik-public : communication avec Traefik
- internal : communication entre services (base de données, cache)
services: wordpress: image: wordpress networks: - traefik-public # Accessible par Traefik - backend # Accès à MySQL labels: - "traefik.http.routers.wp.rule=Host(`blog.example.com`)" - "traefik.docker.network=traefik-public" # Préciser le réseau Traefik
mysql: image: mysql:8 networks: - backend # PAS sur traefik-public = pas accessible depuis InternetExemples pratiques
Section intitulée « Exemples pratiques »Les quatre montages ci-dessous sont complets et fonctionnent tels quels, à deux conditions : que le réseau traefik-public existe déjà et qu'un certresolver nommé letsencrypt soit déclaré dans la configuration statique de Traefik. Ils traitent des problèmes distincts : exposition simple, isolation d'une base de données, répartition sur plusieurs réplicas, et partage d'un même domaine entre deux services.
Application web simple (NGINX)
Section intitulée « Application web simple (NGINX) »Le conteneur ne publie aucun port sur l'hôte : seul Traefik l'atteint, à travers le réseau partagé.
services: nginx: image: nginx:1.31.3-alpine container_name: web volumes: - ./html:/usr/share/nginx/html:ro labels: - "traefik.enable=true" - "traefik.http.routers.web.rule=Host(`www.example.com`)" - "traefik.http.routers.web.entrypoints=websecure" - "traefik.http.routers.web.tls.certresolver=letsencrypt" networks: - traefik-public
networks: traefik-public: external: trueStack WordPress + MySQL
Section intitulée « Stack WordPress + MySQL »MySQL n'est attaché qu'au réseau backend, il reste donc inaccessible depuis Traefik comme depuis Internet. WordPress appartenant à deux réseaux, le label traefik.docker.network lève l'ambiguïté sur celui que le proxy doit emprunter.
services: wordpress: image: wordpress:6 container_name: wordpress environment: WORDPRESS_DB_HOST: mysql WORDPRESS_DB_NAME: wordpress WORDPRESS_DB_USER: wp_user WORDPRESS_DB_PASSWORD: ${WP_DB_PASSWORD} volumes: - wordpress_data:/var/www/html labels: - "traefik.enable=true" - "traefik.http.routers.wordpress.rule=Host(`blog.example.com`)" - "traefik.http.routers.wordpress.entrypoints=websecure" - "traefik.http.routers.wordpress.tls.certresolver=letsencrypt" - "traefik.docker.network=traefik-public" networks: - traefik-public - backend
mysql: image: mysql:8 container_name: wordpress-db environment: MYSQL_DATABASE: wordpress MYSQL_USER: wp_user MYSQL_PASSWORD: ${WP_DB_PASSWORD} MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} volumes: - mysql_data:/var/lib/mysql networks: - backend # Pas exposé sur Internet
networks: traefik-public: external: true backend: driver: bridge
volumes: wordpress_data: mysql_data:API avec plusieurs réplicas
Section intitulée « API avec plusieurs réplicas »Traefik répartit les requêtes entre les réplicas dès lors qu'ils portent les mêmes labels de service, sans configuration supplémentaire. Le healthcheck est ce qui retire un réplica défaillant de la rotation au lieu de continuer à lui adresser du trafic.
services: api: image: myapi:latest deploy: replicas: 3 labels: - "traefik.enable=true" - "traefik.http.routers.api.rule=Host(`api.example.com`)" - "traefik.http.routers.api.entrypoints=websecure" - "traefik.http.routers.api.tls.certresolver=letsencrypt" - "traefik.http.services.api.loadbalancer.server.port=3000" # Healthcheck pour le load balancing - "traefik.http.services.api.loadbalancer.healthcheck.path=/health" - "traefik.http.services.api.loadbalancer.healthcheck.interval=10s" networks: - traefik-publicApplication multi-services (frontend + API)
Section intitulée « Application multi-services (frontend + API) »Les deux routers partagent le même Host et se départagent par le PathPrefix, Traefik retenant la règle la plus spécifique. Le middleware stripprefix retire /api avant transmission, l'API recevant ainsi ses routes à la racine.
services: frontend: image: myfrontend:latest labels: - "traefik.enable=true" - "traefik.http.routers.frontend.rule=Host(`app.example.com`)" - "traefik.http.routers.frontend.entrypoints=websecure" - "traefik.http.routers.frontend.tls.certresolver=letsencrypt" - "traefik.http.services.frontend.loadbalancer.server.port=80" networks: - traefik-public
api: image: myapi:latest labels: - "traefik.enable=true" # Même domaine, path différent - "traefik.http.routers.api.rule=Host(`app.example.com`) && PathPrefix(`/api`)" - "traefik.http.routers.api.entrypoints=websecure" - "traefik.http.routers.api.tls.certresolver=letsencrypt" - "traefik.http.services.api.loadbalancer.server.port=3000" # Middleware pour supprimer le préfixe /api - "traefik.http.routers.api.middlewares=api-stripprefix" - "traefik.http.middlewares.api-stripprefix.stripprefix.prefixes=/api" networks: - traefik-publicDocker Swarm
Section intitulée « Docker Swarm »Le mode Swarm change l'unité observée : Traefik ne suit plus des conteneurs mais des services, dont les labels se déclarent sous deploy.labels. Un label placé au mauvais niveau est simplement ignoré, sans message d'erreur, ce qui rend le symptôme difficile à interpréter. Le provider s'appelle swarm depuis la v3 et le réseau partagé doit être de type overlay.
Différences avec Docker standalone
Section intitulée « Différences avec Docker standalone »Ces cinq écarts expliquent la quasi-totalité des configurations qui fonctionnent en local puis restent invisibles une fois déployées en Swarm.
| Aspect | Docker standalone | Docker Swarm |
|---|---|---|
| Provider | docker | swarm |
| Unité | Conteneur | Service |
| Labels | Sur le conteneur | Dans deploy.labels |
| Réseau | Bridge ou overlay | Overlay obligatoire |
| Scaling | docker compose up --scale | docker service scale |
Configuration provider Swarm
Section intitulée « Configuration provider Swarm »Le bloc remplace le provider docker par swarm. L'option network devient ici pratiquement indispensable : les tâches sont raccordées à un réseau overlay que Traefik doit connaître pour les joindre.
providers: swarm: endpoint: "unix:///var/run/docker.sock" exposedByDefault: false network: traefik-public watch: trueLabels Swarm spécifiques
Section intitulée « Labels Swarm spécifiques »En Swarm, les labels doivent être dans la section deploy.labels :
services: myapp: image: myapp:latest deploy: replicas: 3 labels: - "traefik.enable=true" - "traefik.http.routers.myapp.rule=Host(`app.example.com`)" - "traefik.http.services.myapp.loadbalancer.server.port=8080" networks: - traefik-publicDéploiement en mode Swarm
Section intitulée « Déploiement en mode Swarm »L'option --attachable sur le réseau overlay autorise le raccordement de conteneurs lancés hors Swarm, ce qui est utile pendant une migration progressive.
# Initialiser Swarm (si pas fait)docker swarm init
# Créer le réseau overlaydocker network create --driver=overlay --attachable traefik-public
# Déployer Traefik en mode globaldocker stack deploy -c traefik-stack.yml traefik
# Déployer l'applicationdocker stack deploy -c myapp-stack.yml myappGestion du socket Docker
Section intitulée « Gestion du socket Docker »Le socket Docker est le seul moyen pour Traefik de découvrir les conteneurs, et c'est aussi le point faible de l'architecture : quiconque le lit et l'écrit dispose des droits root sur l'hôte. Le drapeau :ro porte sur le fichier monté, pas sur les requêtes qui transitent par la socket : il ne bloque donc aucun endpoint de l'API. Les deux approches ci-dessous correspondent à deux niveaux d'exposition, l'un tolérable en développement, l'autre attendu en production.
Exposition directe (développement)
Section intitulée « Exposition directe (développement) »En développement, monter le socket directement est acceptable :
volumes: - /var/run/docker.sock:/var/run/docker.sock:roLe :ro (read-only) est une protection minimale, mais Traefik peut toujours lire toutes les informations Docker.
Socket proxy (production)
Section intitulée « Socket proxy (production) »Le proxy de socket s'intercale entre Traefik et le daemon : il n'expose qu'un sous-ensemble de l'API Docker en lecture, sur une socket TCP interne à un réseau dédié. Traefik perd alors tout accès aux endpoints permettant de créer un conteneur, d'exécuter une commande ou de monter un volume, ce qui borne les conséquences d'une compromission.
En production, utilisez docker-socket-proxy pour limiter les endpoints API accessibles :
services: socket-proxy: image: tecnativa/docker-socket-proxy:v0.4.2 container_name: socket-proxy restart: unless-stopped environment: # Endpoints autorisés (lecture seule) CONTAINERS: 1 SERVICES: 1 NETWORKS: 1 TASKS: 1 # Endpoints bloqués BUILD: 0 COMMIT: 0 CONFIGS: 0 DISTRIBUTION: 0 EXEC: 0 IMAGES: 0 INFO: 0 NODES: 0 PLUGINS: 0 SECRETS: 0 SWARM: 0 SYSTEM: 0 VOLUMES: 0 volumes: - /var/run/docker.sock:/var/run/docker.sock:ro networks: - socket-proxy
traefik: image: traefik:v3.7.6 depends_on: - socket-proxy command: - "--providers.docker.endpoint=tcp://socket-proxy:2375" # ...autres options networks: - socket-proxy - traefik-public
networks: socket-proxy: driver: bridge traefik-public: external: trueHealthchecks et load balancing
Section intitulée « Healthchecks et load balancing »Quand plusieurs conteneurs portent les mêmes labels de service, Traefik les traite comme un pool unique et répartit le trafic entre eux. Sans healthcheck, une instance encore en cours de démarrage ou déjà plantée continue de recevoir des requêtes : c'est ce réglage qui sépare une mise à jour transparente d'une série de 502 côté utilisateur.
Configuration des healthchecks
Section intitulée « Configuration des healthchecks »Traefik vérifie régulièrement la santé des backends :
labels: # Healthcheck HTTP - "traefik.http.services.api.loadbalancer.healthcheck.path=/health" - "traefik.http.services.api.loadbalancer.healthcheck.port=8080" - "traefik.http.services.api.loadbalancer.healthcheck.interval=10s" - "traefik.http.services.api.loadbalancer.healthcheck.timeout=3s"| Option | Description | Valeur par défaut |
|---|---|---|
path | Chemin à vérifier | / |
port | Port à vérifier | Port du service |
interval | Intervalle entre vérifications | 30s |
timeout | Timeout de la vérification | 5s |
Stratégies de load balancing
Section intitulée « Stratégies de load balancing »Les sticky sessions renvoient un client vers le même backend grâce à un cookie ajouté par Traefik. À réserver aux applications qui conservent un état en mémoire, car elles neutralisent en partie l'équilibrage.
labels: # Round Robin (défaut) - "traefik.http.services.api.loadbalancer.strategy=round-robin"
# Sticky sessions (affinité) - "traefik.http.services.api.loadbalancer.sticky.cookie=true" - "traefik.http.services.api.loadbalancer.sticky.cookie.name=server_id" - "traefik.http.services.api.loadbalancer.sticky.cookie.secure=true"Dépannage
Section intitulée « Dépannage »Trois symptômes couvrent l'essentiel des blocages avec le provider Docker, et ils partagent une même origine : la configuration attendue n'a jamais été générée. Le dashboard et l'API de Traefik affichent les routers réellement chargés, ce qui permet de distinguer un label ignoré d'un problème de réseau entre le proxy et le conteneur.
Conteneur non détecté
Section intitulée « Conteneur non détecté »Symptômes : Le conteneur ne s'affiche pas dans le dashboard Traefik.
Vérifications :
-
Le label
traefik.enable=trueest présent ?Fenêtre de terminal docker inspect mycontainer | jq '.[0].Config.Labels' -
Le conteneur est sur le bon réseau ?
Fenêtre de terminal docker network inspect traefik-public -
exposedByDefaultest-il àtrueoufalse?
Erreur "Gateway timeout"
Section intitulée « Erreur "Gateway timeout" »Symptômes : Erreur 502 ou 504 après plusieurs secondes.
Causes possibles :
-
Port incorrect : Vérifiez le label
loadbalancer.server.port- "traefik.http.services.myapp.loadbalancer.server.port=8080" -
Réseau différent : Traefik et le conteneur ne sont pas sur le même réseau
- "traefik.docker.network=traefik-public" -
Application non démarrée : Vérifiez les logs du conteneur
Fenêtre de terminal docker logs mycontainer
Conflit de noms
Section intitulée « Conflit de noms »Symptômes : "router already exists" dans les logs Traefik.
Solution : Utilisez des noms uniques pour chaque router et service :
# Mauvais : même nom "app" pour deux services- "traefik.http.routers.app.rule=..." # Conflit !
# Bon : noms uniques- "traefik.http.routers.frontend-app.rule=..."- "traefik.http.routers.api-app.rule=..."Logs et debug
Section intitulée « Logs et debug »L'API sur le port 8080 renvoie les routers et services effectivement chargés : si le vôtre n'y figure pas, le problème vient des labels et non du routage. Le niveau DEBUG journalise en plus chaque événement Docker reçu par le provider.
# Logs Traefikdocker logs traefik -f
# Niveau debugdocker run traefik:v3.7.6 --log.level=DEBUG
# Vérifier les routers via APIcurl http://localhost:8080/api/http/routers | jq
# Vérifier les servicescurl http://localhost:8080/api/http/services | jqÀ retenir
Section intitulée « À retenir »Ces huit points regroupent les décisions qui rendent une configuration Traefik + Docker reproductible : périmètre d'exposition, topologie réseau, accès au socket et nommage des routers.
-
Labels = Configuration : Les labels Docker définissent le routage sans fichier de configuration externe
-
exposedByDefault: false : Toujours désactiver pour éviter d'exposer des conteneurs par accident
-
Réseau dédié : Créez un réseau
traefik-publicexterne et attachez-y tous les services à exposer -
traefik.docker.network : Obligatoire quand un conteneur est sur plusieurs réseaux
-
Socket proxy en production : Utilisez docker-socket-proxy pour sécuriser l'accès au daemon Docker
-
Noms uniques : Chaque router et service doit avoir un nom unique pour éviter les conflits
-
Healthchecks : Configurez-les pour retirer automatiquement les backends en échec
-
Swarm : Utilisez le provider
swarmavec labels dansdeploy.labels
Prochaines étapes
Section intitulée « Prochaines étapes »Bientôt : guides sur les middlewares de sécurité, la configuration TLS avancée, et l'observabilité avec Traefik.