Ah, les joies du docker-compose.yml : quelques services, plusieurs réseaux Docker, Traefik qui détecte parfaitement ton container... et pourtant un magnifique 502 Bad Gateway. Tout semble correctement configuré, les labels sont présents, le container tourne, mais Traefik n'arrive pas à le joindre.
Le coupable peut être tout bêtement un label oublié : traefik.docker.network=proxy.
Quand un container appartient à plusieurs réseaux
Le problème apparaît notamment lorsqu'un service Docker est connecté à plusieurs réseaux. Par exemple, ton container Nginx peut être connecté à un réseau interne permettant de communiquer avec PHP, mais également à un réseau proxy partagé avec Traefik.
services:
nginx:
networks:
- internal
- proxy
Traefik détecte bien le container grâce au provider Docker et à ses labels. Mais il doit également savoir quel réseau Docker utiliser pour joindre le service.
Si le container appartient à plusieurs réseaux et que Traefik choisit le mauvais, il peut essayer de contacter une adresse IP située sur un réseau auquel il n'a lui-même pas accès.
Résultat : le routing existe, Traefik connaît ton domaine et ton service, mais impossible d'atteindre réellement le container derrière. Et tu te retrouves avec un 502 Bad Gateway alors que tout semble pourtant correct.
Indiquer explicitement le réseau à Traefik
La solution consiste à préciser directement dans les labels Docker quel réseau Traefik doit utiliser :
services:
nginx:
networks:
- internal
- proxy
labels:
- "traefik.enable=true"
- "traefik.docker.network=proxy"
- "traefik.http.routers.mon-site.rule=Host(`monsite.fr`)"
- "traefik.http.services.mon-site.loadbalancer.server.port=80"
Le label important est celui-ci :
traefik.docker.network=proxy
Il indique simplement à Traefik : « pour contacter ce container, utilise son adresse IP sur le réseau Docker proxy ».
Traefik doit évidemment être sur le même réseau
Le label ne crée pas le réseau et ne connecte pas automatiquement Traefik dessus. Le container Traefik doit lui aussi appartenir au réseau proxy.
services:
traefik:
networks:
- proxy
networks:
proxy:
external: true
Dans le Compose de ton application, tu peux alors réutiliser ce même réseau externe :
networks:
internal:
proxy:
external: true
Ton application peut continuer à utiliser son réseau internal pour les communications entre Nginx, PHP, Redis ou les autres services. Seuls les containers qui doivent être accessibles par Traefik ont besoin d'être également connectés au réseau proxy.
Le piège à retenir
traefik.docker.network est un label Docker interprété par Traefik. Ce n'est pas une directive Nginx et ça n'a donc absolument rien à faire dans un fichier nginx.conf ou dans un bloc server {}.
Quand Traefik voit correctement un container mais renvoie un 502 Bad Gateway, et que ce container appartient à plusieurs réseaux Docker, vérifier le réseau utilisé par Traefik fait donc partie des premières choses à regarder.
Une petite ligne dans le docker-compose.yml peut éviter de chercher pendant une heure du côté de Nginx, du firewall ou du DNS alors que Traefik essayait simplement de joindre la bonne application par le mauvais réseau.