# 02 — Traefik (Reverse Proxy) > Traefik est le **point d'entrée** unique de l'infrastructure. Il route le trafic vers les bons conteneurs et gère les certificats TLS automatiquement. --- ## 🎯 Rôle de Traefik | Fonction | Description | |---|---| | **Reverse proxy** | Route `.seizeconsulting.com` → conteneur correspondant | | **TLS termination** | Certificats Let's Encrypt automatiques pour tous les sous-domaines | | **HTTP → HTTPS redirect** | Force le HTTPS partout | | **ForwardAuth middleware** | Délègue l'auth à OAuth2-Proxy pour le SSO | | **Dashboard** | UI admin sur `traefik.seizeconsulting.com` | --- ## 📁 Structure ``` ~/docker/traefik/ ├── docker-compose.yml ├── traefik.yml # Config statique (entrypoints, providers) ├── dynamic.yml # Config dynamique (middlewares, routers manuels) └── letsencrypt/ └── acme.json # Certificats stockés (chmod 600) ``` --- ## 📄 docker-compose.yml ```yaml services: traefik: image: traefik:v3.7.1 container_name: traefik restart: unless-stopped command: - "--api.dashboard=true" - "--api.insecure=false" - "--providers.docker=true" - "--providers.docker.exposedbydefault=false" - "--providers.docker.network=web" - "--providers.file.filename=/etc/traefik/dynamic.yml" - "--providers.file.watch=true" - "--entrypoints.web.address=:80" - "--entrypoints.websecure.address=:443" - "--entrypoints.web.http.redirections.entrypoint.to=websecure" - "--entrypoints.web.http.redirections.entrypoint.scheme=https" - "--certificatesresolvers.letsencrypt.acme.email=admin@seizeconsulting.com" - "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json" - "--certificatesresolvers.letsencrypt.acme.httpchallenge=true" - "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web" - "--log.level=INFO" - "--accesslog=true" ports: - "80:80" - "443:443" volumes: - /var/run/docker.sock:/var/run/docker.sock:ro - ./letsencrypt:/letsencrypt - ./dynamic.yml:/etc/traefik/dynamic.yml:ro networks: - web labels: # Dashboard sur traefik.seizeconsulting.com - "traefik.enable=true" - "traefik.http.routers.traefik.rule=Host(`traefik.seizeconsulting.com`)" - "traefik.http.routers.traefik.entrypoints=websecure" - "traefik.http.routers.traefik.tls.certresolver=letsencrypt" - "traefik.http.routers.traefik.service=api@internal" - "traefik.http.routers.traefik.middlewares=traefik-auth" # Basic auth pour le dashboard (à remplacer par OAuth2-Proxy plus tard si on veut SSO) - "traefik.http.middlewares.traefik-auth.basicauth.users=admin:$$apr1$$xxxxxxxx$$xxxxxxxxxxxxxxxxxxxxxxx" networks: web: external: true ``` ⚠️ **Remplacer** : - `admin@seizeconsulting.com` par votre email Let's Encrypt - Le hash basicauth via `htpasswd -nb admin ` --- ## 📄 dynamic.yml (middlewares ForwardAuth) ```yaml http: middlewares: # Middleware ForwardAuth générique pour les outils protégés par OAuth2-Proxy oauth2-headers: forwardAuth: address: "http://oauth2-proxy:4180/oauth2/auth" trustForwardHeader: true # ⚠️ LIGNE CRITIQUE : sans 'Cookie', le SSO ne marche pas authRequestHeaders: - Cookie - Authorization - X-Forwarded-Host - X-Forwarded-Proto - X-Forwarded-Uri authResponseHeaders: - X-Auth-Request-User - X-Auth-Request-Email - X-Auth-Request-Preferred-Username - X-Auth-Request-Groups - X-Auth-Request-Access-Token - X-Forwarded-User - X-Forwarded-Email - X-Forwarded-Preferred-Username - X-Forwarded-Groups - Authorization ``` ⚠️ **Le `Cookie` dans `authRequestHeaders` est ESSENTIEL** — sans ça, le SSO casse complètement (cf. [DECISIONS.md D3](../DECISIONS.md)). --- ## 🚀 Démarrage ```bash cd ~/docker/traefik # Créer l'acme.json touch letsencrypt/acme.json chmod 600 letsencrypt/acme.json # Lancer docker compose up -d # Vérifier les logs docker compose logs -f # Ctrl+C pour quitter ``` ### Vérifications ```bash # Conteneur tourne ? docker ps | grep traefik # Logs propres ? docker logs --tail 30 traefik 2>&1 | grep -i "error\|level=error" # Accès au dashboard ? curl -sI https://traefik.seizeconsulting.com # Doit retourner 401 (demande de basic auth) ``` --- ## 🌐 Comment ajouter un service derrière Traefik ### Méthode 1 — Labels Docker (recommandé) Sur le `docker-compose.yml` du service à exposer, ajouter ces labels : ```yaml services: myservice: image: ... networks: - web labels: - "traefik.enable=true" - "traefik.http.routers.myservice.rule=Host(`myservice.seizeconsulting.com`)" - "traefik.http.routers.myservice.entrypoints=websecure" - "traefik.http.routers.myservice.tls.certresolver=letsencrypt" - "traefik.http.services.myservice.loadbalancer.server.port=8080" # port interne du service networks: web: external: true ``` ⚠️ **Important** : le service doit être sur le réseau `web` partagé avec Traefik. ### Méthode 2 — Avec SSO (via OAuth2-Proxy) Pour les services qui n'ont pas de SSO natif, on ajoute OAuth2-Proxy entre Traefik et le service. Voir [04-oauth2-proxy-pattern.md](./04-oauth2-proxy-pattern.md). --- ## 🐛 Troubleshooting ### "Certificat Let's Encrypt en échec" Symptômes : navigateur dit "Connexion non sécurisée". Causes possibles : 1. **DNS pas propagé** : `dig +short sub.seizeconsulting.com` doit retourner l'IP du serveur 2. **Ports 80/443 bloqués** : firewall + cloud provider 3. **Rate limit Let's Encrypt** : trop de tentatives, attendre 1h 4. **acme.json corrompu** : ```bash sudo rm letsencrypt/acme.json sudo touch letsencrypt/acme.json sudo chmod 600 letsencrypt/acme.json docker compose restart ``` ### "404 page not found" sur un sous-domaine Causes possibles : 1. Le service ciblé n'a pas les bons labels Traefik 2. Le service n'est pas sur le réseau `web` 3. Le port interne du service est incorrect dans `loadbalancer.server.port` 4. La règle `Host(...)` est mal écrite (vérifier les backticks) Vérifier dans le dashboard Traefik : `https://traefik.seizeconsulting.com` → Routers, Services. ### "Bad Gateway 502" Causes possibles : 1. Le service backend est down 2. Le service écoute sur un port différent de celui annoncé à Traefik 3. Le service écoute sur 127.0.0.1 au lieu de 0.0.0.0 ```bash # Vérifier que le service répond bien sur le port interne attendu docker exec -it traefik wget -qO- http://myservice:8080 ``` ### "Le SSO ne marche plus depuis 5 min" Vérifier la config ForwardAuth : ```bash grep -A 10 "oauth2-headers" ~/docker/traefik/dynamic.yml # La ligne "- Cookie" doit être présente dans authRequestHeaders ``` --- ## 🔄 Mise à jour Traefik ```bash cd ~/docker/traefik docker compose pull docker compose up -d ``` ⚠️ Avant une **major version** (v2 → v3 par exemple) : - Lire le CHANGELOG - Tester en local d'abord - Backup de `acme.json` --- ## 📚 Liens utiles - Documentation Traefik : https://doc.traefik.io/traefik/ - Référence des middlewares : https://doc.traefik.io/traefik/middlewares/overview/ - ForwardAuth doc : https://doc.traefik.io/traefik/middlewares/http/forwardauth/