seize-infra-doc/docs/05-applications.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

10 KiB

05 — Applications déployées

Détails de chaque application protégée par SSO.


📋 Vue d'ensemble

App Image Docker SSO via Port interne URL
Gitea gitea/gitea:1.22 OIDC natif 3000 (HTTP), 22 (SSH) git.seizeconsulting.com
n8n n8nio/n8n:latest OAuth2-Proxy 5678 n8n.seizeconsulting.com
Portainer portainer/portainer-ce:latest OAuth2-Proxy 9000 portainer.seizeconsulting.com
Code Server lscr.io/linuxserver/code-server:latest OAuth2-Proxy 8443 code.seizeconsulting.com
Uptime Kuma louislam/uptime-kuma:1 OAuth2-Proxy 3001 status.seizeconsulting.com

🐙 Gitea

Spécificité : SSO OIDC natif

Contrairement aux autres, Gitea ne passe PAS par OAuth2-Proxy. Il a sa propre intégration OIDC.

docker-compose.yml (résumé)

Voir configs/gitea/docker-compose.yml.template.

services:
  gitea:
    image: gitea/gitea:1.22
    container_name: gitea
    environment:
      USER_UID: 1000
      USER_GID: 1000
      GITEA__database__DB_TYPE: postgres
      GITEA__database__HOST: postgres:5432
      GITEA__database__NAME: gitea
      GITEA__database__USER: gitea
      GITEA__database__PASSWD: ${GITEA_DB_PASSWORD}
      GITEA__server__DOMAIN: git.seizeconsulting.com
      GITEA__server__ROOT_URL: https://git.seizeconsulting.com/
      GITEA__server__SSH_DOMAIN: git.seizeconsulting.com
      # Auto-registration via OIDC
      GITEA__oauth2_client__ENABLE_AUTO_REGISTRATION: "true"
      GITEA__oauth2_client__USERNAME: preferred_username
      GITEA__oauth2_client__ACCOUNT_LINKING: auto
      # Désactiver le register manuel (SSO uniquement)
      GITEA__service__DISABLE_REGISTRATION: "true"
    volumes:
      - ./data:/data
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
    ports:
      - "22:22"  # SSH Git
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.gitea.rule=Host(`git.seizeconsulting.com`)"
      - "traefik.http.routers.gitea.entrypoints=websecure"
      - "traefik.http.routers.gitea.tls.certresolver=letsencrypt"
      - "traefik.http.services.gitea.loadbalancer.server.port=3000"
    networks:
      - web
      - backend

Configuration SSO côté Gitea (après premier login)

  1. Aller sur https://git.seizeconsulting.com → setup initial
  2. Créer un compte admin Gitea (local, sera utilisé pour configurer le reste)
  3. Site Administration → Authentication Sources → Add :
    • Type : OAuth2
    • Authentication Name : Zitadel
    • OAuth2 Provider : OpenID Connect
    • Client ID : <de Zitadel>
    • Client Secret : <de Zitadel>
    • OpenID Connect Auto Discovery URL : https://sso.seizeconsulting.com/.well-known/openid-configuration
    • Skip Local 2FA : (Zitadel gère MFA)
  4. Save

Configuration côté Zitadel

Créer une app dans Projects → Infra Seize → Applications :

  • Type : Web
  • Authentication Method : Basic
  • Grant Type : Authorization Code
  • Redirect URL : https://git.seizeconsulting.com/user/oauth2/Zitadel/callback
  • Post-logout Redirect : https://git.seizeconsulting.com/
  • Token Settings : JWT + User profile info dans ID Token

Caractéristiques

  • Auto-registration : à la 1ère connexion via SSO, le compte Gitea est auto-créé
  • Username = trigramme (lu depuis preferred_username Zitadel)
  • Registration manuelle désactivée : SSO obligatoire pour les nouveaux users

Rôles RBAC

Gitea n'utilise pas les rôles Zitadel directement. Les permissions Gitea sont gérées en interne (organizations, teams, repos). Pour l'instant, tous les users ont accès en lecture sur les repos publics.

À configurer plus tard : créer des organizations par BU et donner accès en fonction.


⚙️ n8n

docker-compose.yml (résumé)

services:
  n8n:
    image: n8nio/n8n:latest
    container_name: n8n
    environment:
      DB_TYPE: postgresdb
      DB_POSTGRESDB_HOST: postgres
      DB_POSTGRESDB_PORT: 5432
      DB_POSTGRESDB_DATABASE: n8n
      DB_POSTGRESDB_USER: n8n
      DB_POSTGRESDB_PASSWORD: ${N8N_DB_PASSWORD}
      N8N_ENCRYPTION_KEY: ${N8N_ENCRYPTION_KEY}
      N8N_HOST: n8n.seizeconsulting.com
      N8N_PORT: 5678
      N8N_PROTOCOL: https
      WEBHOOK_URL: https://n8n.seizeconsulting.com/
      # ⚠️ Pas de labels Traefik ici : c'est OAuth2-Proxy qui est exposé
    networks:
      - web
      - backend

Particularités

  • ⚠️ N8N_ENCRYPTION_KEY : critique pour décrypter les workflows et credentials. À sauvegarder absolument.
  • L'auth n8n native est désactivée car OAuth2-Proxy fait l'auth en amont.
  • Les workflows sont stockés dans Postgres (base n8n).

Limitation RBAC

n8n CE (Community Edition) ne supporte pas le RBAC granulaire :

  • Tous les users authentifiés ont accès à TOUS les workflows
  • Pas de notion de "team" ou "project" en CE

→ C'est pourquoi le RBAC se fait côté intranet (cacher la carte aux non-autorisés). Voir DECISIONS.md D7.

Pour vrai RBAC :

  • Soit migrer vers Activepieces (gratuit, multi-tenant natif)
  • Soit acheter n8n Enterprise (~12k€/an)

🐳 Portainer

docker-compose.yml (résumé)

services:
  portainer:
    image: portainer/portainer-ce:latest
    container_name: portainer
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock  # ⚠️ Accès complet à Docker !
      - ./data:/data
    networks:
      - web

Particularités

  • ⚠️ Accès au socket Docker : Portainer a un contrôle total sur tous les conteneurs du serveur. À protéger absolument derrière SSO.
  • Auth Portainer native = créée au premier login, à protéger.
  • RBAC interne dans Portainer CE = très limité.

Limitation RBAC

Portainer CE :

  • 1 seul utilisateur admin
  • Pas d'organisations/teams

→ RBAC sur l'intranet uniquement. Si besoin de vrai RBAC : Portainer Business (~1800€/an) ou migration vers Komodo.


💻 Code Server

docker-compose.yml (résumé)

services:
  code-server:
    image: lscr.io/linuxserver/code-server:latest
    container_name: code-server
    environment:
      PUID: 1000
      PGID: 1000
      TZ: Europe/Paris
      PASSWORD: ${CODE_PASSWORD}  # Fallback si SSO down
      SUDO_PASSWORD: ${CODE_PASSWORD}
      DEFAULT_WORKSPACE: /config/workspace
    volumes:
      - ./config:/config
    networks:
      - web

Particularités

  • VS Code dans le navigateur
  • L'OAuth2-Proxy gère l'auth en amont, mais Code Server a aussi son propre mdp en fallback (CODE_PASSWORD)
  • Workspaces partagés dans ./config/workspace/

Limitation RBAC

Pas de notion de "team" ou "workspace par user" en local. Tout user accède au même workspace.

→ Pour vrai RBAC : OpenVSCode Server (multi-user natif).


📈 Uptime Kuma

docker-compose.yml (résumé)

services:
  uptime-kuma:
    image: louislam/uptime-kuma:1
    container_name: uptime-kuma
    volumes:
      - ./data:/app/data
    networks:
      - web

Particularités

  • Outil de monitoring (HTTP/TCP/Ping checks)
  • Statuspages publiques possibles (mais on les laisse derrière SSO ici)
  • 1 seul user admin

Configuration recommandée

Une fois SSO en place, désactiver le compte admin local ou changer le mdp en quelque chose de très long (le SSO suffit).

Limitation RBAC

Pareil que les autres : 1 seul user, pas de RBAC.

→ Pour vrai RBAC : Gatus (config-as-code, multi-tenant).


🏠 Intranet (page d'accueil)

docker-compose.yml

services:
  intranet:
    image: nginx:alpine
    container_name: intranet
    restart: unless-stopped
    volumes:
      - ./index.html:/usr/share/nginx/html/index.html:ro
      - ./logo.png:/usr/share/nginx/html/logo.png:ro
      - ./roles-mapping.json:/usr/share/nginx/html/roles-mapping.json:ro
      - ./nginx-rbac.conf:/etc/nginx/nginx.conf:ro
    networks:
      - web

Caractéristiques

  • Simple nginx avec un HTML statique
  • Filtrage RBAC côté JavaScript (voir 07-rbac-intranet.md)
  • Nginx fait du sub_filter pour injecter l'email user dans l'HTML
  • L'HTML cache les cartes selon le rôle

Fichiers critiques

Fichier Usage
index.html Le HTML avec les cartes et le JavaScript RBAC
roles-mapping.json Mapping email → role (généré par script Python)
nginx-rbac.conf Config nginx avec sub_filter pour injecter __USER_EMAIL__
logo.png Logo Seize

🗄️ PostgreSQL (principal)

docker-compose.yml

services:
  postgres:
    image: postgres:16-alpine
    container_name: postgres
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      POSTGRES_DB: postgres
    volumes:
      - ./data:/var/lib/postgresql/data
    networks:
      - backend
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      timeout: 5s
      retries: 5

Particularités

  • Postgres mutualisé entre Gitea et n8n (databases séparées dans la même instance)
  • Pas exposé publiquement (réseau backend uniquement)
  • ⚠️ Postgres Zitadel est séparé (dans son propre docker-compose)

Databases hébergées

Database Owner Service
postgres postgres (admin)
gitea gitea Gitea
n8n n8n n8n
authentik authentik Authentik (obsolète)

📦 Volumes critiques par app

App Volume Quoi
Gitea ./data Repos, config, attachments
Portainer ./data Compose stacks, snapshots
Code Server ./config Workspace, settings, plugins
Uptime Kuma ./data Monitors, history, statuspages
Postgres ./data Toutes les DBs (sauf Zitadel)
Zitadel ./postgres-data + ./machinekey Auth complète

🔄 Ajouter une nouvelle app — checklist

Voir OPERATIONS.md section "Ajouter un nouvel outil".

  1. DNS record A <app>.seizeconsulting.com
  2. Créer ~/docker/<app>/ avec docker-compose.yml
  3. Créer l'app dans Zitadel (Project Infra Seize)
  4. Récupérer Client ID + Secret
  5. Créer OAuth2-Proxy dédié ~/docker/oauth2-proxy-<app>/
  6. Tester le login
  7. Ajouter la carte dans ~/docker/intranet/index.html avec data-app="<app>"
  8. Ajouter la ligne dans la matrice RBAC du JavaScript
  9. Restart intranet
  10. Tester avec différents profils