- 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
14 KiB
INSTALL — Déploiement from scratch sur un nouveau serveur
Procédure complète pour reproduire l'infrastructure Seize sur un nouveau serveur.
⏱️ Temps total estimé : 4-6h pour un sysadmin expérimenté.
📋 Prérequis
Côté infrastructure
- Serveur Linux : 4 vCPU, 8 Go RAM minimum (16 Go recommandé), 80 Go disque
- OS : Debian 13 (Trixie) ou Ubuntu 22.04+
- IP publique fixe (chez Scaleway ou autre)
- Ports ouverts : 22 (SSH), 80 (HTTP), 443 (HTTPS)
Côté domaine
- Un domaine que vous contrôlez (ex:
seizeconsulting.com) - Accès à la zone DNS pour ajouter des records A
Côté tiers
- Compte Furious Squad avec droits admin (pour créer un compte API)
- (Optionnel) Compte Microsoft 365 avec admin pour le SMTP
Côté local
- Un PC avec SSH et SCP (Windows PowerShell, Linux, ou macOS)
- Un gestionnaire de mots de passe (Bitwarden, KeePass, 1Password)
🌐 Étape 0 — Configuration DNS
⏱️ 15 min (mais propagation peut prendre 1h+)
Chez votre registrar (Scaleway, OVH, Gandi, etc.), ajouter les records A suivants :
| Record | Type | Valeur |
|---|---|---|
@ (ou seizeconsulting.com) |
A | <IP_DU_SERVEUR> |
sso |
A | <IP_DU_SERVEUR> |
intranet |
A | <IP_DU_SERVEUR> |
git |
A | <IP_DU_SERVEUR> |
n8n |
A | <IP_DU_SERVEUR> |
portainer |
A | <IP_DU_SERVEUR> |
code |
A | <IP_DU_SERVEUR> |
status |
A | <IP_DU_SERVEUR> |
traefik |
A | <IP_DU_SERVEUR> |
Vérification :
nslookup sso.seizeconsulting.com
→ Doit retourner l'IP du serveur.
🐧 Étape 1 — Préparation du serveur
⏱️ 20 min
1.1 — Connexion SSH initiale
ssh root@<IP_DU_SERVEUR>
1.2 — Créer un user non-root
adduser admin
usermod -aG sudo admin
mkdir -p /home/admin/.ssh
cp ~/.ssh/authorized_keys /home/admin/.ssh/
chown -R admin:admin /home/admin/.ssh
chmod 600 /home/admin/.ssh/authorized_keys
1.3 — Hardening SSH
Éditer /etc/ssh/sshd_config :
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
Restart : systemctl restart sshd
1.4 — Reconnexion en tant que l'utilisateur non-root
exit
ssh admin@<IP_DU_SERVEUR>
1.5 — Mise à jour système
sudo apt update && sudo apt upgrade -y
sudo apt install -y curl wget git vim htop unzip
🐳 Étape 2 — Installation Docker
⏱️ 10 min
# Installation Docker depuis le repo officiel
curl -fsSL https://get.docker.com | sudo sh
# Ajouter l'utilisateur au groupe docker
sudo usermod -aG docker $USER
# Se relogger pour prendre en compte le groupe
exit
ssh admin@<IP_DU_SERVEUR>
# Vérification
docker --version
docker compose version
→ Tu dois voir : Docker version 27.x ou plus récent, Docker Compose v2.x
🌐 Étape 3 — Création des réseaux Docker
⏱️ 2 min
docker network create web
docker network create backend
→ Ces réseaux seront partagés entre tous les services.
🛡️ Étape 4 — Installation Traefik
⏱️ 30 min
Voir docs/02-traefik-setup.md pour les détails.
Résumé
mkdir -p ~/docker/traefik/letsencrypt
cd ~/docker/traefik
# Copier le docker-compose.yml depuis configs/traefik/
# Copier traefik.yml et dynamic.yml depuis configs/traefik/
# Adapter les emails Let's Encrypt
docker compose up -d
Vérification :
docker logs traefik
# Doit afficher "Server is up"
Visiter https://traefik.seizeconsulting.com → doit afficher la page de login basic auth.
🔐 Étape 5 — Installation Zitadel
⏱️ 45 min
Voir docs/03-zitadel-setup.md pour les détails complets.
Résumé des points clés
- Créer
~/docker/zitadel/avec sondocker-compose.ymlet.env - Important : Zitadel a son propre Traefik intégré + Postgres dédié
- Lancer :
docker compose up -d - Aller sur
https://sso.seizeconsulting.com/ui/console - Créer le user zitadel-admin initial via console
- Configurer les politiques :
- Password complexity (14 chars, maj+min+chiffres+symboles)
- MFA obligatoire
- Lockout après 5 échecs
⚠️ Sauvegarder le mdp zitadel-admin immédiatement dans le gestionnaire de mots de passe.
🗄️ Étape 6 — Installation Postgres (pour Gitea, n8n)
⏱️ 10 min
mkdir -p ~/docker/postgres/data
cd ~/docker/postgres
# Copier docker-compose.yml et .env.example depuis configs/postgres/
# Renommer .env.example en .env et générer un mdp fort
cat > .env << EOF
POSTGRES_PASSWORD=$(openssl rand -base64 32 | tr -d '+/=')
EOF
chmod 600 .env
docker compose up -d
# Vérification
docker exec -it postgres psql -U postgres -c "SELECT version();"
Créer les databases pour Gitea et n8n
docker exec -it postgres psql -U postgres << EOF
CREATE USER gitea WITH PASSWORD 'PWD_GITEA';
CREATE DATABASE gitea OWNER gitea;
CREATE USER n8n WITH PASSWORD 'PWD_N8N';
CREATE DATABASE n8n OWNER n8n;
EOF
⚠️ Remplacer PWD_GITEA et PWD_N8N par des mdp générés (openssl rand -base64 24) et les stocker dans le gestionnaire.
🐙 Étape 7 — Installation Gitea avec SSO Zitadel
⏱️ 45 min
Voir docs/05-applications.md section Gitea.
Étapes principales
- Créer
~/docker/gitea/avec sondocker-compose.ymlet.env - Démarrer Gitea :
docker compose up -d - Aller sur
https://git.seizeconsulting.com→ faire le setup initial - Dans Zitadel : créer une application "Gitea" dans le project "Infra Seize"
- Configurer dans Gitea : Settings → Authentication Sources → Add OAuth2
- Activer auto-registration dans
app.ini:[oauth2_client] ENABLE_AUTO_REGISTRATION = true USERNAME = preferred_username - Restart Gitea :
docker compose restart
🔐 Étape 8 — Pattern OAuth2-Proxy pour les autres outils
⏱️ 2h (à répéter pour chaque outil)
Voir docs/04-oauth2-proxy-pattern.md pour le pattern complet.
Outils à protéger via OAuth2-Proxy
- n8n
- Portainer
- Code Server
- Uptime Kuma
- Intranet
Étapes par outil (exemple : n8n)
-
Déployer l'outil (sans SSO) :
mkdir -p ~/docker/n8n # Copier docker-compose.yml depuis configs/n8n/ docker compose up -d -
Créer l'application dans Zitadel :
- Console Zitadel → Projects → Infra Seize → Applications → New
- Type : Web
- Authentication Method : Basic
- Grant Types : Authorization Code
- Redirect URL :
https://n8n.seizeconsulting.com/oauth2/callback - Token Type : JWT
- Cocher : User roles inside ID Token, User profile info, Add user roles to access token
-
Récupérer Client ID + Client Secret
-
Déployer OAuth2-Proxy dédié :
mkdir -p ~/docker/oauth2-proxy-n8n # Copier docker-compose.yml et .env.example depuis configs/oauth2-proxy/ # Adapter les valeurs (host, client_id, client_secret, upstream) cd ~/docker/oauth2-proxy-n8n docker compose up -d -
Tester : aller sur
https://n8n.seizeconsulting.com→ doit rediriger vers Zitadel login.
🏠 Étape 9 — Installation Intranet avec RBAC
⏱️ 30 min
Voir docs/07-rbac-intranet.md pour les détails.
Étapes
-
Créer le dossier intranet :
mkdir -p ~/docker/intranet -
Copier les fichiers depuis
configs/intranet/:docker-compose.ymlnginx-rbac.confindex.html.template(à personnaliser)logo.png(le logo Seize)
-
Créer le
roles-mapping.json: Il sera généré plus tard par le scriptgenerate-roles-mapping.py(cf. Étape 10).En attendant, créer un mapping vide :
echo '{}' > roles-mapping.json -
Déployer OAuth2-Proxy pour l'intranet : voir Étape 8 mais avec :
- Host :
intranet.seizeconsulting.com - Upstream :
http://intranet:80
- Host :
-
Démarrer l'intranet :
cd ~/docker/intranet docker compose up -d -
Tester : aller sur
https://intranet.seizeconsulting.com→ login Zitadel → voir les cartes (toutes affichées tant que roles-mapping.json est vide).
👥 Étape 10 — Import des users depuis Furious Squad
⏱️ 1h
Voir docs/06-import-furious.md pour la procédure complète.
Étapes principales
-
Créer un compte API Furious :
- Connexion Furious → Configuration → Générer un nouvel utilisateur d'API
- Cocher les permissions :
User > Searchuniquement - Sauvegarder identifiant + mdp dans le gestionnaire
-
Créer le service account Zitadel :
- Console Zitadel → Users → New → Service user
- Nom :
furious-import-service - Access Token Type : JWT
- Dans Default settings → IAM Members → ajouter ce service user avec rôle
IAM User Manager - Générer une clé : Keys → New → Type JSON → télécharger immédiatement
-
Préparer l'environnement Python :
mkdir -p ~/furious-to-zitadel cd ~/furious-to-zitadel python3 -m venv venv source venv/bin/activate pip install requests pyjwt cryptography -
Copier les scripts depuis
scripts/furious-to-zitadel/du repo. -
Créer le
.env:FURIOUS_USERNAME=<credentials créés à l'étape 1> FURIOUS_PASSWORD=<credentials créés à l'étape 1> FURIOUS_API_URL=https://seize-consulting.furious-squad.com/api/v2chmod 600 .env -
Placer la clé JSON Zitadel :
- Transférer la clé depuis le PC vers le serveur via SCP
chmod 600 zitadelfuriousimportkey.json
-
Lancer l'import :
# Étape A : Lire les users depuis Furious ./read-all-users.sh # → Génère furious-users-raw.json # Étape B : Dry-run (simulation, aucune écriture) python3 import-furious-to-zitadel.py --mode dry-run # Étape C : Test sur 3 users python3 import-furious-to-zitadel.py --mode test # Étape D : Vérifier dans Zitadel UI que les 3 users sont créés avec metadata # Étape E : Import production (les 85 restants) python3 import-furious-to-zitadel.py --mode prod -
Gérer les doublons (si users existaient déjà dans Zitadel) :
# Adapter DUPLICATES dans merge-duplicates.py selon ton cas python3 merge-duplicates.py -
Vérifier le CSV :
wc -l users-credentials.csv # Doit être : 1 header + N users
🎭 Étape 11 — Configuration des rôles RBAC
⏱️ 30 min
Voir docs/07-rbac-intranet.md pour les détails.
Étapes
-
Créer les 8 rôles dans Zitadel :
- Console Zitadel → Projects → Infra Seize → Roles → New
- Créer un par un :
- direction / Direction / hierarchie
- manager / Manager / hierarchie
- expert / Expert / hierarchie
- consultant_senior / Consultant Senior / hierarchie
- consultant_junior / Consultant Junior / hierarchie
- alternant / Alternant / hierarchie
- stagiaire / Stagiaire / hierarchie
- support / Support / hierarchie
-
Activer "Return user roles during authentication" :
- Console Zitadel → Projects → Infra Seize → General
- Cocher "Return user roles during authentication"
- Save
-
Activer "User roles inside ID Token" sur chaque application :
- Pour chaque app (Intranet, n8n, etc.) : Token Settings
- Auth Token Type : JWT
- Cocher : User roles inside ID Token, Include user's profile info, Add user roles to the access token
-
Modifier OAuth2-Proxy pour demander le scope des rôles :
- Pour chaque OAuth2-Proxy : éditer
.env - Modifier :
OAUTH2_PROXY_SCOPE=openid email profile urn:zitadel:iam:org:project:roles - Restart :
docker compose down && docker compose up -d
- Pour chaque OAuth2-Proxy : éditer
-
Lancer les scripts d'attribution :
cd ~/furious-to-zitadel source venv/bin/activate # Générer le mapping email → rôle (pour l'intranet) python3 generate-roles-mapping.py # Attribuer les rôles dans Zitadel (87 users) python3 assign-roles.py -
Copier le mapping vers l'intranet :
cp roles-mapping.json ~/docker/intranet/ -
Restart de l'intranet :
cd ~/docker/intranet docker compose down docker compose up -d -
Test final :
- Login en incognito avec un user (ex: consultant_junior)
- Doit voir uniquement les cartes autorisées (Gitea + Code Server par défaut)
✅ Étape 12 — Validation finale
⏱️ 30 min
Checklist de validation
- Tous les conteneurs
Up:docker ps - Tous les sous-domaines répondent en HTTPS
- Login Zitadel fonctionne avec MFA
- Login intranet fonctionne et filtre les cartes
- Login Gitea fonctionne avec auto-registration
- Login n8n / Portainer / Code Server / Uptime Kuma fonctionne
- Le service account Furious peut lire l'API Furious
- Les scripts Python sont opérationnels
- Les fichiers sensibles ont
chmod 600 - Les
.envne sont pas committés sur Git - Backup automatique en place (à mettre en place — voir OPERATIONS.md)
🚨 Points d'attention pendant l'install
Ne pas oublier
- ✅ Sauvegarder TOUS les secrets dans le gestionnaire de mdp
- ✅ Configurer le firewall (ufw ou iptables) pour limiter aux ports 22/80/443
- ✅ Tester chaque étape avant de passer à la suivante
- ✅ Documenter les écarts par rapport à cette procédure si tu en fais
Pièges classiques
- ❌ Oublier d'ajouter le record DNS avant de tester le HTTPS (Let's Encrypt échoue)
- ❌ Lancer
docker compose up -dsans avoir créé le.env(erreurs cryptiques) - ❌ Donner IAM_OWNER au service account (utiliser IAM_USER_MANAGER)
- ❌ Coller un secret dans une conversation IA (gestionnaire de mdp uniquement)
📚 Pour aller plus loin
Une fois l'install terminée, consulter :
- OPERATIONS.md pour la maintenance quotidienne
- docs/09-troubleshooting.md pour les problèmes fréquents
- HANDOVER.md pour les actions à mener