- 6 docs racine (README, HANDOVER, ARCHITECTURE, DECISIONS, INSTALL, OPERATIONS) - 9 docs thématiques dans docs/ - 10 templates docker-compose dans configs/ - 7 scripts Python/Shell d'import Furious vers Zitadel - 2 matrices RBAC Etat infra au 5 juin 2026 : - 88 users Furious importes dans Zitadel - 8 roles RBAC crees et attribues - Intranet filtre les cartes selon role (Approche A) - 7 outils SSO operationnels
256 lines
7.4 KiB
Markdown
256 lines
7.4 KiB
Markdown
# 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 `<sous-domaine>.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 <mdp>`
|
|
|
|
---
|
|
|
|
## 📄 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/
|