Files
nas-runbooks/common/hermes-hub-deploiement.md
T

96 lines
4.6 KiB
Markdown

# Hermes Hub — Déploiement et Exploitation Multi-Univers sur VPS
**Instance auteur** : gemini / nabil
**Date** : 2026-08-19
**Tags** : hermes, hub, multi-univers, vps, tailscale, cloudflare-access, fastapi, filebrowser, dsh
**Statut** : valide
---
## Problème
Nabil dispose de 4 instances Hermes strictement cloisonnées :
- **TT** (`hermes-tt`, port 3010, NAS Synology) — Achats Zone Sud, Tunisie Telecom
- **Nyora** (`hermes-nyora`, port 3020, NAS Synology) — Venture perso, Dr Nexum
- **Perso** (`hermes-perso`, port 3031, NAS Synology) — Famille, personnel, santé
- **Nabil** (`hermes-nabil`, local loopback, VPS Contabo) — Master agent & DeepSeek Harness (DSH)
L'objectif est d'offrir une interface web unifiée sur le VPS Contabo avec :
1. Un **Workspace Switcher** latéral fluide et étanche entre les 4 univers.
2. Un **Sélecteur Toggle DSH** (conception Claude Design) pour basculer instantanément entre la session de dialogue et l'explorateur de fichiers DSH (`/u/nabil/files/`).
3. L'absence totale de fuite de contexte, de mémoire JS ou de cookies de session entre univers.
4. La sécurisation intégrale via **Cloudflare Access** (OTP Email + 2FA) et maillage **Tailscale** sans exposition de port WAN sur le NAS ni d'IP publique directe sur le VPS.
---
## Contexte et contraintes
- **Réseau** : Communication exclusive via le maillage **Tailscale** (`100.86.197.88` NAS ↔ `100.94.90.119` VPS).
- **Port Hermes Perso** : Port **3031** fixé définitivement (port 3030 bloqué et purgé).
- **Sécurité & Auth** : Authentification **Cloudflare Access** en amont du tunnel Cloudflare (`hub.yesminedor.tn`).
- **Filebrowser DSH** : Image épinglée en SemVer **`filebrowser/filebrowser:v2.32.0`** (jamais `:latest`), lancée avec `--noauth` (délégué à Cloudflare Access) et thème sombre (`--branding.theme=dark`).
- **Montage DSH** : Montage Read-Write strict sur `/home/dsh-agent/dsh-vps/workspace` vers `/srv` (la racine utilisateur avec clés SSH et wrappers reste protégée).
- **UID/GID** : Hub exécuté sous `1026:100`, Filebrowser sous `:` (1001:1001).
---
## Ce qui NE fonctionne PAS
| Tentative | Erreur obtenue / Risque | Raison de l'échec / Solution adoptée |
|-----------|-------------------------|--------------------------------------|
| Tunnel WireGuard wg-easy | 0 B reçus, timeout | wg-easy décommissionné le 08/07/2026. Remplacé nativement par Tailscale (44 ms). |
| Port 3030 pour hermes-perso | Port bloqué / conflit | Processus docker-proxy orphelin sur l'hôte NAS. Port 3031 fixé et 3030 bloqué via iptables. |
| Tag `:latest` sur Filebrowser | Risque de régression | Règle de gouvernance : tag SemVer exact fixé sur `filebrowser/filebrowser:v2.32.0`. |
| Auth interne filebrowser.db | Double login inutile | Cloudflare Access + 2FA constitue le garde-fou unique suffisant. Filebrowser démarré avec `--noauth`. |
| Montage de la racine `/home/dsh-agent` | Fuite de clés SSH | Restriction stricte au seul sous-dossier `workspace/`. |
---
## Solution validée
### 1. Dépôt & Code source
- Dépôt Gitea : `http://192.168.100.33:3232/bolbol/hermes-hub.git`
- Stack : FastAPI + Async Streaming Proxy (`httpx`) + Design Tokens + Sélecteur Toggle DSH (Claude Design).
### 2. Déploiement sur VPS Contabo (`100.94.90.119`)
```bash
# 1. Cloner le dépôt
git clone http://bolbol:PASSWORD@100.86.197.88:3232/bolbol/hermes-hub.git ~/hermes-hub
cd ~/hermes-hub
# 2. Configurer l'environnement (.env)
cp .env.example .env
# Définir HUB_SECRET (openssl rand -hex 32) et les UIDs dsh-agent
# 3. Lancer le stack Hub + Filebrowser
docker compose up -d --build
```
### 3. Routage & Cloudflare Tunnel
- Ingress Cloudflare Tunnel (`cloudflared`) : `hub.yesminedor.tn -> http://127.0.0.1:8080`
- Application Cloudflare Access : politique Email OTP autorisée.
---
## Vérification
```bash
# 1. Vérification santé Hub
curl -fsS http://127.0.0.1:8080/api/health
# Résultat attendu : {"status":"healthy","universes_configured":4}
# 2. Vérification connectivité multi-univers
curl -fsS http://127.0.0.1:8080/api/universes
# 3. Test du proxy Filebrowser
curl -fsS -I http://127.0.0.1:8080/u/nabil/files/
# Résultat attendu : HTTP/1.1 200 OK
```
---
## Pièges spécifiques
- **Cloisonnement des cookies** : L'attribut `Path` des en-têtes `Set-Cookie` émis par les backends est réécrit à la volée vers `Path=/u/{universe_id}/` pour interdire toute collision entre univers sous le même domaine.
- **Purge mémoire front-end** : À chaque changement d'univers, l'iframe charge d'abord `about:blank` pour détruire le state DOM/JS résiduel avant de monter le nouvel univers.