seize-infra-doc/docs/09-troubleshooting.md
Hedi Kalboussi 1e90a85359 Documentation initiale infra Seize — passation J7
- 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
2026-06-05 17:49:43 +00:00

11 KiB

09 — Troubleshooting

Problèmes fréquents rencontrés et leurs solutions.


🔍 Démarrage de tout diagnostic

Avant d'essayer n'importe quoi, vérifier :

# 1. Conteneurs en route
sudo docker ps

# 2. Espace disque
df -h /

# 3. Mémoire libre
free -h

# 4. Charge système
uptime

# 5. Logs Traefik récents (souvent la source des problèmes)
sudo docker logs --tail 50 traefik

🔴 Problèmes critiques

"Tout est down, je ne peux plus accéder à rien"

Diagnostic

# SSH au serveur
ssh hedi@<server>

# Vérifier Docker
sudo systemctl status docker
sudo docker ps | wc -l
# Doit afficher > 20 (24 conteneurs attendus)

# Vérifier ports 80/443
sudo netstat -tlnp | grep -E "80|443"

# Vérifier les certificats Let's Encrypt
sudo ls -la ~/docker/traefik/letsencrypt/

Causes possibles

Cause 1 — Docker daemon down :

sudo systemctl restart docker
sudo docker compose -f ~/docker/traefik/docker-compose.yml up -d
# Démarrer dans l'ordre : Traefik, puis Zitadel, puis les autres

Cause 2 — Disque plein :

# Nettoyer Docker
sudo docker system prune -a --volumes
# Nettoyer logs si > 1 Go
sudo du -sh /var/lib/docker/containers/*/
sudo truncate -s 0 /var/lib/docker/containers/*/*-json.log

Cause 3 — IP du serveur a changé :

  • Vérifier DNS : dig +short sso.seizeconsulting.com
  • Si IP différente → mettre à jour DNS chez le registrar

"Le SSO ne fonctionne plus depuis 5 minutes"

Symptôme : tous les outils SSO renvoient une boucle de redirection ou un "Bad Gateway".

Diagnostic — Vérifier dans cet ordre

1. Zitadel répond ?

curl -sI https://sso.seizeconsulting.com
# Doit retourner 200 ou 302

Si non : docker logs zitadel-zitadel-api-1 --tail 50

2. Traefik ForwardAuth marche ?

grep -A 8 "authRequestHeaders" ~/docker/traefik/dynamic.yml
# La ligne "- Cookie" doit être présente

3. OAuth2-Proxy de l'outil tourne ?

sudo docker ps | grep oauth2-proxy
# Tous doivent être Up

4. Logs OAuth2-Proxy ?

sudo docker logs --tail 50 oauth2-proxy
sudo docker logs --tail 50 oauth2-proxy-n8n
# Chercher : "error", "unauthorized", "context deadline exceeded"

Solutions courantes

Solution 1 : Restart de Traefik

cd ~/docker/traefik
docker compose down
docker compose up -d

Solution 2 : Restart d'OAuth2-Proxy de l'outil concerné

cd ~/docker/oauth2-proxy-<outil>
docker compose down
docker compose up -d

Solution 3 : Vérifier que les certificats TLS sont OK

echo | openssl s_client -connect sso.seizeconsulting.com:443 2>/dev/null | openssl x509 -noout -dates
# notAfter doit être dans > 7 jours

C'est le bug historique. Cf. DECISIONS.md D3.

Fix immédiat

Vérifier que ~/docker/traefik/dynamic.yml contient :

http:
  middlewares:
    oauth2-headers:
      forwardAuth:
        address: "http://oauth2-proxy:4180/oauth2/auth"
        authRequestHeaders:
          - Cookie         # ← CRITIQUE
          - Authorization
        authResponseHeaders:
          - X-Auth-Request-User
          - X-Auth-Request-Email

Si la ligne - Cookie manque → l'ajouter, puis :

cd ~/docker/traefik
docker compose restart

🟡 Problèmes courants

"Le certificat Let's Encrypt va expirer / a expiré"

Traefik renouvelle automatiquement. Si pas le cas :

# Vérifier les logs Let's Encrypt
sudo docker logs traefik 2>&1 | grep -i "letsencrypt\|acme" | tail -20

# Causes possibles :
# 1. Rate limit Let's Encrypt (trop de tentatives) → attendre 1h
# 2. DNS pas correct → vérifier dig
# 3. Port 80 bloqué → vérifier firewall

# Forcer le renouvellement
cd ~/docker/traefik
docker compose down
docker compose up -d

⚠️ Cas critique : acme.json corrompu :

sudo cp letsencrypt/acme.json letsencrypt/acme.json.backup
sudo rm letsencrypt/acme.json
sudo touch letsencrypt/acme.json
sudo chmod 600 letsencrypt/acme.json
docker compose restart

→ Recrée tous les certificats (peut prendre 5 min).


"Un user ne peut pas se logger"

Vérifier dans cet ordre

1. Le compte existe-t-il dans Zitadel ?

  • Console Zitadel → Users → Search par email
  • Status doit être "Active" (pas "Inactive" ou "Deleted")

2. L'email est-il vérifié ?

  • Console → User → General → Email verified ?
  • Si non : Actions → Resend verification (mais SMTP doit être configuré)
  • Ou : Set as verified manually

3. Le MFA est-il bloqué ?

  • Si l'user a perdu son téléphone : Reset MFA
  • Console → User → Multi-factor authentication → Remove

4. Lockout actif ?

  • Console → User → Activity → vérifier les failed attempts
  • Reset : Actions → Unlock

5. L'user a-t-il un rôle ?

  • Si "Only authorized users" est coché sur le project, il faut un rôle
  • Console → User → Authorizations → Add role

"Le script Python d'import échoue"

Erreur 401 / 403

cd ~/furious-to-zitadel
source venv/bin/activate

# Vérifier la clé JSON
python3 -c "
import json
data = json.load(open('zitadelfuriousimportkey.json'))
print('UserId:', data.get('userId'))
print('KeyId:', data.get('keyId'))
"
# Si erreur → la clé est corrompue, en régénérer une

# Vérifier les permissions du service account
# Console Zitadel → Users → furious-import-service → IAM Members
# Doit avoir IAM_USER_MANAGER

Erreur 400 sur certains users

# Voir les détails dans le log
tail -100 import.log | grep -B 2 "ERROR"

# Causes courantes :
# - Email invalide dans Furious (espaces, caractères spéciaux)
# - Mdp trop court / ne respecte pas la policy
# - Username déjà existant

Erreur de connexion Furious

./test-auth.sh
# Doit retourner un JSON valide
# Si 401 → identifiants Furious à régénérer
# Si timeout → API Furious peut être down, vérifier status

"L'intranet ne montre pas les bonnes cartes"

Voir 07-rbac-intranet.md section Troubleshooting.

Rapide :

  1. Console JS (F12) → vérifier le log [RBAC] User: ... | Rôle: ...
  2. Si rôle null → roles-mapping.json à régénérer
  3. Si email = __USER_EMAIL__ → nginx sub_filter pas appliqué

"Le conteneur xxx redémarre en boucle"

# Voir les logs
sudo docker logs <container> --tail 50

# Voir le statut détaillé
sudo docker inspect <container> --format '{{.State.Health}}'

# Causes courantes :
# 1. Healthcheck failed → vérifier la commande de healthcheck
# 2. Erreur de config (mauvais env) → vérifier .env
# 3. Volume manquant ou permissions → vérifier les paths
# 4. Port déjà utilisé → docker compose down + up

# Voir les events Docker récents
sudo docker events --since 10m

"Espace disque saturé"

# Voir où va l'espace
sudo du -sh /var/lib/docker/* | sort -h
sudo du -sh /home/*

# Nettoyer Docker
sudo docker system prune -a --volumes
# ⚠️ Supprime tout ce qui n'est pas utilisé activement

# Nettoyer les logs Docker
sudo find /var/lib/docker/containers -name "*-json.log" -exec truncate -s 0 {} \;

# Configurer la rotation des logs (à mettre dans /etc/docker/daemon.json) :
{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m",
    "max-file": "3"
  }
}
# Restart Docker après modif
sudo systemctl restart docker

🟢 Problèmes mineurs

"L'image d'un conteneur est obsolète"

cd ~/docker/<service>
docker compose pull
docker compose up -d

"Comment voir les logs en temps réel ?"

docker compose logs -f
# Ctrl+C pour quitter

"Comment redémarrer juste un service sans toucher les autres ?"

sudo docker restart <container_name>
# Plus rapide qu'un docker compose

"Comment exécuter une commande dans un conteneur ?"

sudo docker exec -it <container> sh
# ou bash si dispo

🔧 Débogage avancé

Nginx Diagnostic (debug RBAC)

⚠️ Procédure temporaire — supprimer immédiatement après usage.

Pour voir ce que les headers HTTP contiennent réellement :

# Créer une config nginx diagnostic
cat > ~/docker/intranet/nginx-diagnostic.conf << 'EOF'
events {}
http {
    server {
        listen 80;
        location /debug {
            add_header Content-Type text/plain;
            return 200 "=== Headers reçus ===
X-Forwarded-User: $http_x_forwarded_user
X-Forwarded-Email: $http_x_forwarded_email
X-Forwarded-Preferred-Username: $http_x_forwarded_preferred_username
X-Forwarded-Groups: $http_x_forwarded_groups
Authorization: $http_authorization
";
        }
        location / { try_files $uri /index.html =404; }
    }
}
EOF

# Modifier docker-compose pour utiliser cette config
nano ~/docker/intranet/docker-compose.yml
# Ajouter le volume : ./nginx-diagnostic.conf:/etc/nginx/nginx.conf:ro

# Restart
docker compose up -d

# Accéder à : https://intranet.seizeconsulting.com/debug
# (en étant logué)

# ⚠️ AVANT DE FERMER : restaurer la config normale !
rm ~/docker/intranet/nginx-diagnostic.conf
# Remettre nginx-rbac.conf dans docker-compose.yml

Décoder un token JWT

Si tu as un token et veux voir son contenu (claims, exp, etc.) :

# Méthode 1 : jwt.io (en ligne, ATTENTION ne pas coller de vrais tokens)
# Méthode 2 : ligne de commande

TOKEN="<ton_jwt>"
echo $TOKEN | cut -d "." -f2 | base64 -d 2>/dev/null | python3 -m json.tool

Vérifier la communication réseau entre 2 conteneurs

sudo docker exec -it traefik wget -qO- http://intranet:80
sudo docker exec -it oauth2-proxy wget -qO- http://intranet:80

Si erreur → vérifier que les conteneurs partagent un réseau Docker commun.

Voir les connexions actives

sudo ss -tunlp | grep -E "80|443"

# Connexions en cours
sudo netstat -anp | grep ESTABLISHED | grep ":443" | wc -l

📋 Checklist quand quelque chose ne va pas

  • Tous les conteneurs Up ? → sudo docker ps
  • DNS OK ? → dig +short <domain>
  • HTTPS valide ? → curl -sI https://<domain>
  • Logs Traefik sans erreur ? → docker logs --tail 50 traefik | grep -i error
  • Logs OAuth2-Proxy sans erreur ? → docker logs --tail 50 oauth2-proxy*
  • Espace disque OK ? → df -h /
  • Mémoire OK ? → free -h
  • Authentification Zitadel OK depuis incognito ?
  • Vérifier que rien n'a été modifié récemment (fichier .yml ou .env)

📞 Quand escalader

Vers Philippe (sponsor)

  • Service critique down > 30 min
  • Demande de modification d'architecture
  • Validation d'une décision business

Vers le support Scaleway

  • Serveur inaccessible (panne réseau ou hardware)
  • Quota dépassé sur le compte
  • Problème de facturation

Vers le support Furious

  • API Furious down ou très lente
  • Permissions API qui ne fonctionnent pas malgré une bonne config
  • Problèmes de données RH (départs mal renseignés, etc.)

Vers la communauté Zitadel


📚 Liens vers les docs internes