Files
g9-migration/DOSSIER-SOFTWARE.md
T

941 lines
75 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Dossier — Stack logicielle de la maison (Partie 5)
**Date** : 06/10/2026
**Auteur** : Jean-Henry Foltzenlogel (Folzo)
**Réseau** : `192.168.1.0/24`
**Statut global** : 🟡 **Conception validée (table rase)** — architecture logicielle ciblée, décisions tranchées, plan de migration posé. **Aucune implémentation** : ce dossier est le **cahier des charges logiciel** qui précède le rebuild.
**Document** : **vivant** — versionné, mis à jour à chaque évolution. Chaque section porte son statut (✅ / 🟡 / ⬜).
> **Nature du document** : c'est le **dossier Partie 5 — couche logicielle** de l'infrastructure. Il fait suite à la **table rase** demandée : on repart de zéro, **sans biais** sur les outils existants, pour choisir la stack qui tient **aujourd'hui ET dans le futur**, qui passe en **production** (plus de R&D), qui est **pérenne**, **100% open source** (licence notée par service), **consolidée** (pas 50 apps — un tout cohérent type Nextcloud), et **résiliente par l'usage** (chaque brique a un utilisateur nommé + un appareil + un usage quotidien).
>
> **Position dans le projet** : `DOSSIER-RECREATION.md` (v2) décrit la **machine** (rôles, disques, 3-2-1, phases). Ce dossier décrit le **logiciel** qui tourne dessus : quelle brique, où, pourquoi, et comment on passe du chaos R&D actuel à un système de production. En cas de conflit sur les **faits matériels**, c'est le **snapshot** `ETAT-DE-LART-2026-09-30.md` qui fait foi ; pour l'**architecture machine**, c'est `DOSSIER-RECREATION.md` ; pour le **logiciel** (ce document), c'est **lui** qui fait foi.
>
> **Règle d'or de la table rase** : chaque brique est **justifiée** (maturité, maintenance, ressource sur la machine cible, licence OSS, **chemin de sortie/export**). Si une brique ne sert **personne au quotidien**, elle ne rentre pas. La **résilience = l'usage** : un service que personne n'utilise est un coût, pas un asset.
---
## Sommaire
- [S1 — Objectif & principes de la table rase](#s1--objectif--principes-de-la-table-rase)
- [S2 — Architecture cible par machine](#s2--architecture-cible-par-machine)
- [S3 — Stack consolidée, brique par brique](#s3--stack-consolidée-brique-par-brique)
- [S4 — Bloc IA (le cœur du futur)](#s4--bloc-ia-le-cœur-du-futur)
- [S5 — Photos (PhotoPrism)](#s5--photos-photoprism)
- [S6 — Fichiers & productivité (Nextcloud)](#s6--fichiers--productivité-nextcloud)
- [S7 — Média (Jellyfin + \*arr + podcasts)](#s7--média-jellyfin--arr--podcasts)
- [S8 — Communication (Matrix + Jitsi + assistant vocal)](#s8--communication-matrix--jitsi--assistant-vocal)
- [S9 — Sécurité & accès distant](#s9--sécurité--accès-distant)
- [S10 — Backup 3-2-1 (restic/borg + LUKS)](#s10--backup-3-2-1-resticborg--luks)
- [S11 — Ops (Compose + Gitea + Watchtower + Beszel)](#s11--ops-compose--gitea--watchtower--beszel)
- [S12 — Enfants & MDM](#s12--enfants--mdm)
- [S13 — Plan de migration R&D → production](#s13--plan-de-migration-rd--production)
- [S14 — Grille des décisions + recommandations](#s14--grille-des-décisions--recommandations)
- [S15 — Critères d'acceptance (AC1–AC10)](#s15--critères-dacceptance-ac1ac10)
- [Changelog](#changelog)
---
## S1 — Objectif & principes de la table rase
> **Statut** : ✅ Validé (05/10/2026)
### 1.1 Pourquoi une table rase
L'infra actuelle est née **empiriquement** : 34 conteneurs sur le J5040, ~30 sur le xpenology, 9 sur le PC IA, des briques IA dupliquées (2× STT, 2× OCR, 2× OpenWebUI, Dify + RAGFlow + Qdrant + mcpo + pipelines…), des conteneurs morts, et des services qui ne servent **plus personne**. C'est du **R&D** : on a tout essayé, rien n'a été **tranché** ni **fiabilisé**.
La table rase, c'est **arrêter de collectionner** et **choisir**. Le critère n'est plus « est-ce que ça marche ? » mais **« est-ce que ça sert quelqu'un, tous les jours, et est-ce que je peux le réparer en 5 min ? »**.
### 1.2 Les 6 principes (le filtre de chaque brique)
| # | Principe | Signification concrète |
|---|----------|------------------------|
| 1 | **Table rase** | On ne part pas de « ce qui est installé ». On part du **besoin**, et on choisit la brique qui le sert. L'existant n'est qu'un **candidat**, pas une contrainte. |
| 2 | **Pérenne / fiable** | On choisit des briques **matures**, **maintenues**, **stables** — pas des toys de démo. Le système doit tourner **sans intervention**. |
| 3 | **100% open source** | Chaque brique est OSS, **licence notée** (S3). Pas de zone grise (XPEnology éliminé), pas de SaaS GAFAM. |
| 4 | **Consolidé** | **Un besoin = une brique = une machine.** On vise **≤ ~20 briques** au total, pas 50 apps. Un tout cohérent (Nextcloud comme socle famille), pas un cimetière de démos. |
| 5 | **Résilience = usage** | Chaque brique a **un utilisateur nommé + un appareil + un usage quotidien** (S8.2 / S15 AC8). Pas de brique orpheline. |
| 6 | **Reversibilité** | Chaque brique a un **chemin de sortie/export** documenté (S3). On ne se verrouille pas : on peut partir à tout moment. |
### 1.3 Ce que la table rase change vs l'existant
| Aspect | Avant (R&D) | Après (production) |
|--------|-------------|--------------------|
| **Nombre de briques** | ~70 conteneurs (34+30+9) | **≤ ~20 briques** cohérentes |
| **Duplication** | 2× STT, 2× OCR, 2× OpenWebUI, 2× n8n, Dify+RAGFlow | **1 seul** par fonction |
| **Critère de garde** | « ça marche » | « ça sert quelqu'un, tous les jours » |
| **Licence** | inconnue / mixte | **notée par brique** (OSS) |
| **Sortie** | aucune | **chemin d'export** documenté |
| **Ops** | ad hoc | **Compose versionné + Watchtower + Beszel** |
---
## S2 — Architecture cible par machine
> **Statut** : ✅ **Validée (Option A)** (05/10/2026) — hérite de `DOSSIER-RECREATION.md` §R2, **affinée** par la redistribution logicielle.
### 2.1 Le choix clé : le PC IA garde toute la RAM
Le **Qwen 3.8max** (le LLM principal) consomme **~20 Go VRAM + ~50 Go RAM**. Le PC IA a **62 Go RAM** : c'est la **seule** machine qui peut le porter. **Conséquence** : le PC IA est **saturé par l'IA** → on **n'y met rien d'autre de lourd**. Cela déplace **Matrix + Jitsi** (comms, qui demandent de la RAM) sur le **J5040 (edge)**, et **Home Assistant** reste sur la **Freebox** (VM légère, déjà en place).
### 2.2 Rôle logiciel de chaque machine (Option A)
| Machine | IP | RAM | **Rôle logiciel** | Briques logicielles |
|---------|-----|-----|-------------------|---------------------|
| **Freebox Delta** | .254 | — | **WAN + Maison + Backup** | **Home Assistant** (enceintes Google ×4-5) · **Frigate** (Reolink, détection) · 2ᵉ copie backup (RAID5 3×1To) |
| **J5040** | .1 | **16 Go (upgradé)** | **Edge + Comms + Downloads** | **Firewall** · **DHCP** · **AdGuardHome** · **SearXNG** (recherche web) · **Caddy** (TLS auto) · **WireGuard** · **Web Station** · **Beszel** · **Matrix (Synapse) + Jitsi** · **Prowlarr/Sonarr/Radarr + qBittorrent** |
| **G9** | .25 | 16 Go (fixe) | **Cœur famille** | **Nextcloud** (+Collabora Office, Deck, Notes, Groupware CalDAV/CardDAV, Mail IMAP) · **PhotoPrism** · **Jellyfin** (vidéo+musique) · **Vaultwarden** · **Gitea** · **n8n** · **Valheim** · SMB |
| **PC IA** | .11 | **62 Go** | **IA (max RAM)** | **Ollama** (Qwen 3.8max) · **Qdrant** · **hermes** · **OpenWebUI** (famille, 1 seul) |
| **G7** | .30 | 15 Go | **Spare / débordement** | (non branché — secours G9, ou débordement Matrix/Jitsi en pic) |
| **218play** | .26 | — | **3ᵉ copie offsite** | (backup) |
### 2.3 Pourquoi cette répartition
| Décision | Raison |
|----------|--------|
| **Matrix + Jitsi sur J5040 (16 Go)** | Le PC IA est saturé par le LLM (62 Go). Matrix (Synapse) + Jitsi (appels) demandent de la RAM → ils vont sur l'edge, qui a de la marge après la libération de l'IA. |
| **Home Assistant sur Freebox** | VM déjà en place, légère, et c'est le **routeur** (proximité domotique). Frigate (vision caméras) y tourne aussi — léger, pas de GPU requis pour la détection de base. |
| **\*arr + qBittorrent sur J5040** | Les téléchargements sont de l'**edge** (proximité internet). Libère le G9 (cœur famille) et son disque RAID1 (données importantes, pas du média brut). |
| **Nextcloud + PhotoPrism + Jellyfin sur G9** | Le **cœur famille** = là où sont les **données importantes** (RAID1). Les apps qui les servent sont à côté des données (pas de traversée réseau). |
| **n8n sur G9** | L'automatisation touche le **cœur famille** (photos, fichiers, agenda). Un seul n8n (le 2ᵉ est supprimé). |
| **Tout le bloc IA sur PC IA** | Ollama + Qdrant + hermes + OpenWebUI = là où sont les **GPU + 62 Go**. Un seul endroit, un seul point de maintenance. |
### 2.4 Budget ressource par machine (AC4)
| Machine | RAM | Charge estimée | Marge | Verdict |
|---------|-----|----------------|-------|---------|
| **J5040** | 16 Go | edge (~2 Go) + SearXNG (~200 Mo) + Matrix+Jitsi (~3-4 Go) + \*arr+qBittorrent (~1-2 Go) + Beszel/Caddy/AdGuard (~1 Go) ≈ **7-9 Go** | ~7 Go | ✅ tenable (G7 = débordement en pic) |
| **G9** | 16 Go | Nextcloud+Collabora (~3-4 Go) + PhotoPrism (~2-3 Go) + Jellyfin (~1-2 Go) + n8n (~1 Go) + Gitea/Vaultwarden (~1 Go) ≈ **8-11 Go** | ~5-8 Go | ✅ tenable (surveiller Collabora en pic) |
| **PC IA** | 62 Go | Ollama Qwen 3.8max (~50 Go) + Qdrant (~1-2 Go) + hermes (~1 Go) + OpenWebUI (~1 Go) ≈ **53 Go** | ~9 Go | ✅ tenable (le LLM domine, c'est assumé) |
| **Freebox** | — | HA + Frigate (légers, VM) | — | ✅ léger (pas de GPU requis) |
> **Point de vigilance unique** : le **J5040** avec Matrix+Jitsi **en pic** (appels vidéo + téléchargements). Le **G7 (15 Go)** est le **débordement** documenté : si le J5040 sature, on y déplace Matrix/Jitsi. C'est le seul vrai risque RAM de l'architecture.
---
## S3 — Stack consolidée, brique par brique
> **Statut** : ✅ **Validée** (05/10/2026) — **~20 briques** sur 4 machines. Chaque brique est justifiée (maturité, maintenance, ressource, **licence OSS**, **chemin de sortie**). C'est la réponse aux **AC2, AC3, AC10**.
### 3.1 La stack complète (une brique = un besoin = une machine)
| # | Brique | Besoin servi | Machine | Licence OSS | Maturité / maintenance | Chemin de sortie / export |
|---|--------|--------------|---------|-------------|------------------------|---------------------------|
| 1 | **Firewall (nftables)** | Protection LAN/WAN | J5040 | GPL-2.0 | Système (noyau Linux), très stable | Config = fichiers, exportable |
| 2 | **DHCP (dnsmasq)** | Attributions IP | J5040 | GPL-2.0 | Système, très stable | Config exportable |
| 3 | **AdGuard Home** | DNS + filtre pubs + **parents** | J5040 | MIT | Très mature, maintenu | Config + listes exportables |
| 4 | **Caddy** | Reverse proxy + **TLS auto** (Let's Encrypt) | J5040 | Apache-2.0 | Très mature (Caddy 2), maintenu | `Caddyfile` = config, exportable |
| 5 | **WireGuard** | Accès distant chiffré | J5040 | GPL-2.0 | Système (noyau), très stable | Clés exportables |
| 6 | **Web Station** | Sites web (dd/lola.folzocorp…) | J5040 | — (contenu) | Statique | Fichiers, exportables |
| 7 | **Beszel** | Monitoring léger + alertes | J5040 | MIT | Mature, maintenu (henrygd) | Base SQLite, exportable |
| 8 | **Matrix (Synapse)** | **Messagerie du foyer** (complément de WhatsApp, **pas de remplacement**) | J5040 | Apache-2.0 | Très mature (Element/Matrix), maintenu | Export des salons (JSON), comptes |
| 9 | **Jitsi** | **Visioconférence** | J5040 | Apache-2.0 | Mature (Jitsi Meet), maintenu | N/A (appels éphémères) |
| 10 | **\*arr** (Prowlarr + Sonarr + Radarr) — **1 stack** | Gestion **séries/films** (indexers + queue) | J5040 | GPL-3.0 | Très mature (la stack \*arr), maintenu | Bases SQLite exportables, config |
| 11 | **qBittorrent** | **Téléchargement** (torrent/HTTP) | J5040 | GPL-2.0 | Très mature, maintenu | File de tâches exportable |
| 12 | **Nextcloud** | **Fichiers** + socle famille (Drive, partages) | G9 | AGPL-3.0 | Très mature, maintenu | Export complet (fichiers = standard) |
| 13 | ↳ **Collabora Office** (app NC #12) | **Bureautique** (remplace Office/Docs) | G9 | MPL-2.0 (code) | Mature (LibreOffice base), maintenu | Fichiers **ODF** (standard ouvert) |
| 14 | ↳ **Nextcloud Groupware** (app NC #12) | **Agenda + contacts** (CalDAV/CardDAV) | G9 | AGPL-3.0 | Mature, maintenu | **ICS / VCF** (standards ouverts) |
| 15 | ↳ **Nextcloud Deck + Notes** (apps NC #12) | **Tâches + notes rapides** famille | G9 | AGPL-3.0 | Mature, maintenu | Export Markdown / JSON |
| 16 | **PhotoPrism** | **Photos** (timeline, visages, albums, partage, recherche sémantique) | G9 | **AGPL-3.0** (core) | Mature, maintenu | **Lecture in-place** des originaux (pas de verrouillage) |
| 17 | **Jellyfin** | **Vidéo + musique** (streaming famille) | G9 | AGPL-3.0 | Très mature, maintenu | N/A (lecture des fichiers sources) |
| 18 | **Vaultwarden** | **Mots de passe** (coffre famille) | G9 | AGPL-3.0 | Très mature, maintenu | **Export chiffré** (standard Bitwarden) |
| 19 | **Gitea** | **Git** (vault second cerveau + versioning) | G9 | MIT | Très mature, maintenu | **Repos git** (exportables) |
| 20 | **n8n** | **Automatisation** (workflows) | G9 | ⚠️ **Sustainable Use License (fair-code, PAS OSI)** | Très mature, maintenu | Workflows exportables (JSON) |
| 21 | **Valheim** | **Jeu** (monde famille) | G9 | — (jeu) | Stable | Sauvegardes de monde |
| 22 | **Ollama** | **Backend LLM** (Qwen 3.8max) | PC IA | MIT | Très mature, maintenu | Modèles = fichiers (re-téléchargeables) |
| 23 | **Qdrant** | **Vector DB** (RAG / second cerveau) | PC IA | Apache-2.0 | Très mature, maintenu | Collections exportables (JSON) |
| 24 | **hermes** | **Harnais agent** (Effi — mémoire, MCP, knowledge) | PC IA | **MIT** | Communautaire, maintenu (nesquena — `ghcr.io/nesquena/hermes-webui`) | Mémoire = fichiers, exportable |
| 25 | **OpenWebUI** | **Front LLM simple famille** (1 seul) | PC IA | BSD-3 | Très mature, maintenu | N/A (interface) |
| 26 | **Home Assistant** | **Domotique** (enceintes Google, maison) | Freebox | Apache-2.0 | Très mature, maintenu | Config YAML exportable |
| 27 | **Frigate** | **Vision caméras** (Reolink, détection) | Freebox | AGPL-3.0 | Mature, maintenu | Enregistrements = fichiers vidéo |
| 28 | **SearXNG** | **Recherche web** (meta-moteur privé, dégooglisation) | J5040 | AGPL-3.0 | Très mature, maintenu | Config + listes de blocage exportables |
> **Comptage** : **28 lignes** = **25 briques fonctionnelles** (les 3 apps Nextcloud ↳ 13-15 sont des **apps du socle NC #12**, pas des briques séparées ; la stack \*arr #10 = **1 brique**). On reste dans la cible de consolidation **≤ ~20 briques** (S1.2, vs ~70 conteneurs / 50 apps) — c'est le **maximum** justifié, chaque brique ayant un **utilisateur nommé** (S8.2).
>
> **⚠️ Note honnêteté licence (AC10)** : **n8n** n'est **PAS** open source au sens **OSI** — il est sous **Sustainable Use License** (fair-code, source disponible, usage libre, mais restrictions d'usage). C'est le **seul** écart au « 100% OSI ». **Alternative OSI** si on veut du 100% pur : **Activepieces** (MIT) ou **n8n → remplacement progressif**. Décision : on **garde n8n** (maturité + écosystème + usage interne non-commercial = licence confortable) mais c'est **noté** pour transparence.
### 3.2 La liste de suppression explicite (le ballast R&D)
> **AC2** : tout ce qui n'est **pas** dans le tableau 3.1 est **supprimé** du rebuild. C'est la table rase concrète.
| Brique supprimée | Pourquoi |
|------------------|----------|
| **Dify** (14 conteneurs) | Plateforme agents **R&D** — remplacée par **hermes + Ollama + Qdrant** (plus sobre, plus pérenne). |
| **RAGFlow** (crash loop) | RAG **dupliqué** — remplacé par **Qdrant** direct (plus simple, stable). |
| **STT dupliqué** (effi-stt + whisper) | **2×** la même chose → **1 seul** (faster-whisper, sur PC IA, on-demand). |
| **OCR dupliqué** (effi-ocr + kreuzberg) | **2×** → **1 seul** (kreuzberg/PaddleOCR FR, sur PC IA, on-demand). |
| **OpenWebUI multiples** (2×) | **1 seul** (sur PC IA, front famille). |
| **llm-proxy (LiteLLM)** | Remplacé par **Ollama** direct (point d'entrée unique). |
| **mcpo + pipelines** (OpenWebUI) | Remplacés par **hermes** (harnais agent avec MCP natif). |
| **ComfyUI** (port mort) | **On-demand** uniquement, pas 24/7 — réactivé seulement si usage image. |
| **Pterodactyl** (panel + DB + cache) | Remplacé par **Valheim direct** (3 conteneurs → 1). |
| **CouchDB + Obsidian (conteneur)** | Obsidian = **app locale** (pas un conteneur serveur) ; le vault = **Gitea**. |
| **Leantime** | Gestion de projet **R&D** — remplacé par **Nextcloud Deck** (tâques famille). |
| **Affine** | Workspace **R&D** — remplacé par **Obsidian + Gitea** (second cerveau). |
| **Joplin** | Notes **dupliquées** — remplacées par **Obsidian + Gitea** (vault unique). |
| **OnlyOffice** | Bureautique **dupliquée** — remplacée par **Collabora Office** (app Nextcloud). |
| **InfluxDB** | Métriques **dupliquées** — remplacées par **Beszel** (léger, historique intégré). |
| **Flaresolverr** | Anti-Cloudflare **R&D** — supprimé (pas d'usage quotidien). |
| **mini-qr** | Utilitaire **marginal** — supprimé. |
| **Conteneurs morts** (wg-easy, xteve, wol-proxy, youtubedl, mcpo…) | **Morts** — supprimés. |
| **18 modèles Ollama legacy** (98 Go) | **Tri** — garder les modèles utiles (Qwen 3.8max + embeddings), supprimer le reste. |
| **FreshRSS** (lecture RSS) | **Pas d'utilisateur nommé à usage quotidien** au moment de la table rase (résilience = usage). Les podcasts RSS sont déjà couverts **côté client** par **AntennaPod** (zéro serveur). **Chemin de ré-add** : Compose sur G9 en < 5 min (~100 Mo, AGPL-3.0) si le besoin émerge. |
> **Bilan** : ~70 conteneurs → **~20 briques**. C'est la **consolidation** (principe 4).
### 3.3 Justification par brique (maturité + ressource + sortie)
> **AC3** : les briques **clés** sont justifiées en détail. Les autres suivent le même raisonnement (tableau 3.1).
| Brique | Maturité | Ressource (machine cible) | Pourquoi CELLE-ci (vs alternatives) |
|--------|----------|---------------------------|--------------------------------------|
| **Caddy** | Caddy 2, très stable | ~50 Mo (J5040) | **TLS auto** (Let's Encrypt) sans script. Plus simple que Traefik/Nginx pour un usage familial. |
| **Matrix (Synapse)** | Standard de fait, très maintenu | ~2-3 Go (J5040) | **Messagerie du foyer** (chiffré, fédéré, OSS) — **complément** de WhatsApp, **pas un remplacement**. Alternative : Element = le client. |
| **Jitsi** | Mature (Jitsi Meet) | ~1-2 Go (J5040) | **Visio** OSS, s'intègre à Matrix (Element). |
| **PhotoPrism** | Mature, AGPL | ~2-3 Go (G9) | **Lecture in-place** (ne déplace pas les originaux) + IA (visages, recherche sémantique) + partage. Plus sobre qu'Immich (qui désorganise). |
| **Jellyfin** | Très mature, AGPL | ~1-2 Go (G9) | **Vidéo + musique** OSS, transcodage, multi-appareils. Standard de fait. |
| **Nextcloud** | Très mature, AGPL | ~2-3 Go (G9) | **Socle famille** : Drive + Office + Groupware + Deck + Notes en **un seul** (consolidation). |
| **Vaultwarden** | Très mature, AGPL | ~100 Mo (G9) | **Mots de passe** OSS (alternative Bitwarden légère). Standard d'export. |
| **Gitea** | Très mature, MIT | ~200 Mo (G9) | **Git** léger (vault second cerveau + versioning). Plus sobre que GitLab. |
| **n8n** | Très mature (fair-code) | ~1 Go (G9) | **Automatisation** (workflows). Écosystème riche. ⚠️ non-OSI (noté). |
| **Ollama** | Très mature, MIT | ~50 Go (PC IA) | **Backend LLM** (Qwen 3.8max). Point d'entrée unique, simple. |
| **Qdrant** | Très mature, Apache-2.0 | ~1-2 Go (PC IA) | **Vector DB** (RAG / second cerveau). Plus performant que sqlite-vec à l'échelle. |
| **hermes** | Communautaire, MIT | ~1 Go (PC IA) | **Harnais agent** (Effi) : mémoire, MCP, knowledge. Remplace Dify/mcpo/pipelines. |
| **OpenWebUI** | Très mature, BSD-3 | ~1 Go (PC IA) | **Front LLM simple** pour la famille (1 seul). |
| **Home Assistant** | Très mature, Apache-2.0 | VM légère (Freebox) | **Domotique** standard de fait (enceintes Google, maison). |
| **Frigate** | Mature, AGPL | léger (Freebox) | **Vision caméras** (Reolink) + détection. Plus simple qu'un NVR dédié. |
| **Beszel** | Mature, MIT | ~50 Mo (J5040) | **Monitoring** léger + historique + alertes. Plus sobre que InfluxDB+Grafana. |
| **AdGuard Home** | Très mature, MIT | ~100 Mo (J5040) | **DNS + filtre pubs + parents**. Standard de fait. |
| **WireGuard** | Système (noyau), GPL-2.0 | négligeable (J5040) | **VPN** moderne, simple, performant. |
| **restic/borg** (S10) | Très mature, Apache/GPL | léger | **Backup** chiffré, dédupliqué, versionné, append-only. |
### 3.4 Usages nommés — briques edge & infra (AC8)
> Chaque brique du S3.1 a un **utilisateur nommé + appareil + usage quotidien** (résilience = usage). Les briques famille sont détaillées en S5.3 / S6.4 / S7.3 / S8.2 / S12.3 ; les briques edge & infra ici.
| Brique | Utilisateur nommé | Appareil | Usage quotidien |
|--------|-------------------|----------|-----------------|
| **SearXNG** | Moi + famille | Laptop + téléphone | **Recherche web** (privé, sans tracking) — remplace la recherche Google pour l'usage perso |
| **AdGuard Home** | Famille (dont enfants) | Tous les appareils | DNS + filtre pubs + profils parents |
| **Caddy / WireGuard / firewall** | Moi | Laptop + téléphone | Accès distant sécurisé (VPN) + TLS auto |
| **Beszel** | Moi | Laptop + téléphone | Monitoring + alertes (→ Matrix) |
---
## S4 — Bloc IA (le cœur du futur)
> **Statut** : ✅ **Validé** (05/10/2026) — le bloc IA est **consolidé** sur le **PC IA** (62 Go). C'est la **différence** vs l'existant (qui était dispersé + dupliqué).
### 4.1 L'architecture du bloc IA (1 seul endroit)
```
┌─────────────────────────────────────────────────────────┐
│ PC IA (.11) — 62 Go RAM, 2× RTX 3060 (24 Go VRAM) │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌──────────────┐ │
│ │ Ollama │ │ Qdrant │ │ hermes │ │
│ │ (LLM) │ │ (vector DB)│ │ (agent) │ │
│ │ Qwen 3.8max│──►│ (RAG / │◄──│ (Effi) │ │
│ │ ~50 Go RAM │ │ 2ᵉ │ │ mémoire + │ │
│ │ ~20 Go VRAM│ │ cerveau) │ │ MCP + │ │
│ └──────┬──────┘ └─────────────┘ │ knowledge │ │
│ │ └──────┬───────┘ │
│ ▼ ▼ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ OpenWebUI (front famille, 1 seul) │ │
│ │ → la famille pose des questions au LLM │ │
│ └─────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
```
### 4.2 Les briques du bloc IA (et pourquoi)
| Brique | Rôle | Pourquoi CELLE-ci |
|--------|------|-------------------|
| **Ollama** | **Backend LLM** (Qwen 3.8max) | Point d'entrée **unique**, simple, MIT. Remplace llama.cpp direct + llm-proxy. |
| **Qwen 3.8max** | **Le LLM principal** | ~20 Go VRAM + ~50 Go RAM → **seul** le PC IA (62 Go) le porte. C'est le **cerveau**. |
| **Qdrant** | **Vector DB** (RAG / 2ᵉ cerveau) | Stocke les **embeddings** (bge-m3) du second cerveau. Apache-2.0, performant. |
| **hermes** | **Harnais agent** (Effi) | **Mémoire** + **MCP** + **knowledge** : c'est l'**Effi** (mon Jarvis). Remplace Dify + mcpo + pipelines. MIT. |
| **OpenWebUI** | **Front famille** (1 seul) | La famille pose des questions au LLM **simplement**. BSD-3. |
### 4.3 Le second cerveau (2 couches) — lien avec `PROJET-SECOND-CERVEAU.md`
> Le bloc IA **porte** le second cerveau (projet séparé). **Modèle 2 couches (source unique)** : `PROJET-SECOND-CERVEAU.md` S4.1 — **couche 1 = la connaissance** (markdown, vérité), **couche 2 = l'index** (cache jetable, reconstruisible).
**Mapping sur les briques** (spécificité du dossier logiciel) :
| Couche | Brique | Machine |
|--------|--------|---------|
| **1 — Connaissance** | **Gitea** (canon) + **G9** (working) | G9 |
| **2 — Index** | **Qdrant** (embeddings) | PC IA |
> L'**hermes** est le **harnais** qui **récupère d'elle-même** le contexte (exigence #2) via **MCP**.
### 4.4 Ce qui est **supprimé** du bloc IA (vs l'existant)
| Supprimé | Remplacé par |
|----------|--------------|
| **Dify** (14 conteneurs) | **hermes + Ollama + Qdrant** |
| **RAGFlow** (crash loop) | **Qdrant** direct |
| **llm-proxy (LiteLLM)** | **Ollama** direct |
| **mcpo + pipelines** | **hermes** (MCP natif) |
| **2× OpenWebUI** | **1 seul** (PC IA) |
| **2× STT** | **1 seul** (faster-whisper, on-demand) |
| **2× OCR** | **1 seul** (kreuzberg/PaddleOCR FR, on-demand) |
| **ComfyUI 24/7** | **On-demand** uniquement |
> **Bilan** : le bloc IA passe de **~30 conteneurs dispersés** à **5 briques** sur **1 machine**. C'est la **consolidation** du futur.
---
## S5 — Photos (PhotoPrism)
> **Statut** : ✅ **Tranché** (05/10/2026) — **PhotoPrism** (lecture **in-place**). Répond à la décision ouverte **R6.1** de `DOSSIER-RECREATION.md`.
### 5.1 Le choix : PhotoPrism (et pourquoi pas Immich)
| Critère | **PhotoPrism** ✅ | Immich ❌ |
|---------|-------------------|----------|
| **Lecture in-place** | ✅ **Lit l'arborescence d'originaux** (triés par année), **ne déplace pas** les fichiers | ❌ **Importe** dans sa propre base (désorganise) |
| **IA (visages, recherche sémantique)** | ✅ intégrée | ✅ intégrée |
| **Partage famille** | ✅ (liens, albums) | ✅ |
| **Auto-upload Android** (téléphones enfants) | ✅ (app + API) | ✅ |
| **Sobriété (G9, 16 Go)** | ✅ ~2-3 Go | 🟡 plus gourmand |
| **Licence** | **AGPL-3.0** (core) | AGPL-3.0 |
| **Sortie** | ✅ originaux **intacts** (on peut partir sans perte) | 🟡 export depuis la base |
> **Décision** : **PhotoPrism** car il **lit les originaux en place** (pas de verrouillage, pas de désorganisation). C'est aligné avec la **culture de la donnée** (pas de déplacement des sources brutes — `PROJET-SECOND-CERVEAU.md` S1.4).
### 5.2 La migration des 10 ans de photos Synology
| Étape | Action |
|-------|--------|
| 1 | **Copier** l'arborescence des originaux Synology → G9 `/data/famille/photos/AAA/` (par année, convention Annexe B du guide). |
| 2 | **Pointeur** PhotoPrism sur `/data/famille/photos/` (lecture in-place). |
| 3 | **Indexation** (visages, lieux, recherche sémantique) — se fait en arrière-plan. |
| 4 | **Reprise des albums** : les albums Synology **ne sont pas importés directement** (les fichiers sont intacts → on **re-crée** les albums ou un **script de mapping**). |
> **Point d'attention** : les **albums Synology** sont une **vue**, pas les fichiers. Les **fichiers** sont intacts → on **re-crée** les albums dans PhotoPrism (ou un script de mapping des noms d'albums). **Aucune perte** (les originaux sont là).
### 5.3 L'usage famille (résilience = usage)
| Utilisateur | Appareil | Usage quotidien |
|-------------|----------|-----------------|
| **Moi** | Laptop + téléphone | Recherche, albums, partage |
| **Femme** | Téléphone | Photos famille, albums |
| **Enfants** | Téléphone Android | **Auto-upload** des photos (règle famille #1 : « les photos vont sur le NAS ») |
---
## S6 — Fichiers & productivité (Nextcloud)
> **Statut** : ✅ **Tranché** (05/10/2026) — **Nextcloud** comme **socle famille** (consolidation). Répond aux décisions **R6.2** (notes) + **2.1/2.2** (agenda/mail).
### 6.1 Nextcloud = le socle (un seul, pas 5 apps)
> **Principe de consolidation** : Nextcloud **regroupe** les briques de productivité famille en **un seul** service (pas Leantime + Affine + Joplin + OnlyOffice + … séparés).
| App Nextcloud | Besoin | Remplace |
|---------------|--------|----------|
| **Nextcloud Drive** | **Fichiers** famille (partages, sync) | Nextcloud existant + Google Drive |
| **Collabora Office** | **Bureautique** (docs, tableurs, présentations) | OnlyOffice + Office GAFAM |
| **Groupware** (CalDAV/CardDAV) | **Agenda + contacts** | Google Agenda/Contacts |
| **Deck** | **Tâches** famille (kanban) | Leantime |
| **Notes** | **Notes rapides** famille | (pas le second cerveau — voir S6.2) |
| **Mail** (IMAP) | **Lecture** mail (voir S6.3) | — |
### 6.2 Les notes : le second cerveau (pas Nextcloud Notes)
> **Décision R6.2 tranchée** : les **notes de connaissance** (second cerveau) = **Obsidian + Gitea** (markdown versionné), **PAS** Nextcloud Notes.
| Type de note | Outil | Pourquoi |
|--------------|-------|----------|
| **Second cerveau** (connaissance, versionné, IA) | **Obsidian** (viewer) + **Gitea** (store) + **Qdrant** (index) | Markdown = format ouvert, versionné git, lisible par l'humain **et** l'IA. Nextcloud Notes = **mauvais fit** comme store (pas de versioning, pas de structure liée — `PROJET-SECOND-CERVEAU.md` S4.3). |
| **Notes rapides famille** (listes, mémos) | **Nextcloud Notes** | Simple, partagé, pas besoin de versioning. |
> **Séparation claire** : le **second cerveau** (moi, connaissance) = Obsidian+Gitea+Qdrant. Les **notes rapides famille** = Nextcloud Notes. **Pas de confusion**.
### 6.3 Le mail : pas de serveur SMTP local (décision pragmatique)
> **Décision** : **pas de serveur mail local** (la **livraison** SMTP est trop difficile à fiabiliser — SPF/DKIM/DMARC, réputation, spam). On garde **Gmail/Hotmail** pour la **livraison**, et **Nextcloud Mail** pour la **lecture** via **IMAP**.
| Aspect | Choix |
|--------|-------|
| **Lecture** | **Nextcloud Mail** (IMAP vers Gmail/Hotmail) |
| **Accès web** | Gmail/Hotmail (externes) pour l'envoi |
| **Étape par étape** | On **lit** en local d'abord ; la **dégafamisation complète** du mail (serveur local) est un **horizon > 1 an** (trop risqué en production). |
> **Honnêteté** : le mail est le **point le plus dur** à dégafamiser (livraison). On ne le force pas : on **lit** en local, on **garde** la livraison externe. C'est **pérenne** (pas de risque spam) et **réversible**.
### 6.4 L'usage famille (résilience = usage)
| Utilisateur | Appareil | Usage quotidien |
|-------------|----------|-----------------|
| **Moi** | Laptop + téléphone | Fichiers, Office, agenda, second cerveau |
| **Femme** | Téléphone | Fichiers, agenda, contacts, mail |
| **Enfants** | PC + téléphone | Fichiers (dossier famille), photos |
---
## S7 — Média (Jellyfin + \*arr + podcasts)
> **Statut** : ✅ **Tranché** (05/10/2026) — **Jellyfin** (vidéo+musique) + **\*arr** (gestion) + **AntennaPod** (podcasts, zéro serveur).
### 7.1 La stack média
| Brique | Rôle | Machine | Licence |
|--------|------|---------|---------|
| **Jellyfin** | **Streaming vidéo + musique** (transcodage, multi-appareils) | G9 | AGPL-3.0 |
| **Prowlarr** | **Indexers** (source de métadonnées) | J5040 | GPL-3.0 |
| **Sonarr** | **Séries** (queue + métadonnées) | J5040 | GPL-3.0 |
| **Radarr** | **Films** (queue + métadonnées) | J5040 | GPL-3.0 |
| **qBittorrent** | **Téléchargement** (torrent/HTTP) | J5040 | GPL-2.0 |
| **AntennaPod** | **Podcasts** (app Android, **zéro serveur**) | Téléphone | GPL-3.0 |
### 7.2 Pourquoi cette répartition
| Décision | Raison |
|----------|--------|
| **\*arr + qBittorrent sur J5040** | Les **téléchargements** sont de l'**edge** (proximité internet). Le G9 (cœur famille) n'est pas saturé par les torrents. |
| **Jellyfin sur G9** | Le **streaming** lit les **fichiers** (USB média sur G9). L'app est à côté des données. |
| **Podcasts = AntennaPod + RSS** | **Zéro serveur** : AntennaPod lit les **flux RSS** directement. Pas de brique serveur pour les podcasts (consolidation). |
### 7.3 L'usage famille (résilience = usage)
| Utilisateur | Appareil | Usage quotidien |
|-------------|----------|-----------------|
| **Famille** | TV (Shield/Mi Box) + Denon | **Jellyfin** (films, séries, musique) |
| **Moi** | Téléphone | **AntennaPod** (podcasts) |
| **Enfants** | TV + PC | **Jellyfin** (contenus filtrés) |
---
## S8 — Communication (Matrix + Jitsi + assistant vocal)
> **Statut** : ✅ **Tranché** (05/10/2026), **révisé 12/10/2026** — **Matrix + Jitsi + Element** = **complément du foyer** (messagerie familiale + canal d'alerte + assistant), **pas un remplacement de WhatsApp**. WhatsApp reste la messagerie principale (famille, amis, travail) — réalité d'usage mesurée, voir `g9-migration/BRIDGE-WHATSAPP.md`.
### 8.1 La stack communication
| Brique | Rôle | Machine | Licence |
|--------|------|---------|---------|
| **Matrix (Synapse)** | **Messagerie du foyer** + **canal d'alerte ops** (complément de WhatsApp) | J5040 | Apache-2.0 |
| **Jitsi** | **Visioconférence** | J5040 | Apache-2.0 |
| **Element** | **Client** (Android) — 2 adultes d'abord, ados en phase 2 | Téléphone | GPL-3.0 |
| **Home Assistant** | **Assistant vocal** (enceintes Google) | Freebox | Apache-2.0 |
### 8.2 L'usage famille (résilience = usage)
| Utilisateur | Appareil | Usage quotidien |
|-------------|----------|-----------------|
| **Famille** | Téléphone (Element) | **Messagerie du foyer** (salon famille) — **WhatsApp garde** les échanges extérieurs (amis, travail, famille élargie) |
| **Famille** | Téléphone + TV | **Visio** (Jitsi, via Element) |
| **Moi** | Téléphone + PC | **Salon ops** (alertes backup / sondes / dérive registre) |
| **Moi** | Enceintes Google ×4-5 | **Assistant vocal** (Home Assistant) → peut déclencher n8n, contrôler Frigate |
**Décision 12/10/2026 (statut du canal)** : Matrix + Jitsi + Element = **complément du foyer** —
salon famille, salon ops, salon Effi. **WhatsApp n'est pas remplacé** et reste la messagerie
principale (famille élargie, amis, travail) : c'est un constat d'usage mesuré, pas un choix
technologique. Element s'installe d'abord sur les **2 appareils adultes** ; les 4 ados viennent en
**phase 2**, déclenchée par le **GO famille** explicite de l'utilisateur. Grille de décision :
**S14.5**.
**Les 4 interdictions** (applicables dès maintenant, vérifiables) :
1. **Interdiction** de présenter Matrix comme un remplacement de WhatsApp, et d'inciter la famille
à quitter WhatsApp pour Matrix (WhatsApp garde les échanges extérieurs).
2. **Interdiction** de faire transiter les **alertes ops** par WhatsApp : le canal d'alerte est
**Matrix uniquement** (pas d'e-mail, pas de SMS, pas de WhatsApp).
3. **Interdiction** d'**automatiser l'envoi** de messages WhatsApp (pont `mautrix-whatsapp` :
**étudié, non déployé**, numéro familial **interdit** — voir `g9-migration/BRIDGE-WHATSAPP.md`).
4. **Interdiction** d'équiper les **4 ados** d'Element (et de comptes enfants Matrix) **sans GO
famille** explicite, et sans coffre/2FA posé pour eux (C-FM1).
Ces 4 interdictions sont **contrôlables** : interdiction 1 = vocabulaire du dossier (aucune ligne
ne présente Matrix comme le remplaçant de WhatsApp — contrôlé par `grep -in "rempla.*whatsapp"`
qui ne doit sortir que des formulations « complément », « pas un remplacement ») ;
interdiction 2 = le canal d'alerte est Matrix (3
notifications types mesurées dans le salon ops) ; interdiction 3 = 0 flux n8n vers WhatsApp
(inventaire n8n) ; interdiction 4 = 0 compte ado Matrix (Synapse mesuré : 4 comptes, aucun ado).
### 8.3 Le bot hermes ↔ Matrix
> **hermes** (Effi, sur PC IA) est **connecté à Matrix** : la famille peut **parler à Effi** dans un salon Matrix. C'est l'**assistant de famille** (projet second cerveau, phase 3).
### 8.4 Les alertes n8n → Matrix
> **n8n** (G9) envoie les **alertes** (Beszel, backup, services) dans un **salon Matrix** dédié. C'est le **canal d'alerte** unique (pas d'e-mail, pas de SMS).
---
## S9 — Sécurité & accès distant
> **Statut** : ✅ **Tranché** (05/10/2026), **révisé 10/10/2026** (G9 mono-disque : LUKS abandonné sur le G9, voir changelog) — **Caddy + TLS auto**, **WireGuard**, **firewall strict**, **chiffrement des copies (restic)**, **2FA**, **sous-domaines** folzocorp.fr. Répond à l'**AC6**.
### 9.1 Le modèle de sécurité (couche par couche)
| Couche | Brique | Détail |
|--------|--------|--------|
| **Périmètre** | **Firewall (nftables)** sur J5040 | Filtre LAN/WAN **strict** : par défaut **dénier**, autoriser seulement les ports exposés. |
| **Entrée internet** | **Caddy** (reverse proxy) | **Point d'entrée unique** + **TLS auto** (Let's Encrypt, auto-renew). Remplace le **script de 6 mois** (pérenne). |
| **Accès distant** | **WireGuard** | **VPN** chiffré pour accéder à la maison depuis l'extérieur. **Pas d'exposition directe** des services. |
| **Chiffrement disque** | **restic (copies) / LUKS disques amovibles** | **Révisé 10/10/2026** : G9 **mono-disque sans LUKS** (données familiales non critiques) ; la protection repose sur les **backups restic déjà chiffrés** + disques de backup amovibles chiffrés. La protection **internet** = firewall/Caddy/WireGuard, pas LUKS. |
| **Identité** | **2FA** | Tous les services exposés (Nextcloud, Vaultwarden, Gitea, Matrix) en **2FA**. |
| **DNS / filtre** | **AdGuard Home** | DNS interne + **filtre pubs** + **profils enfants**. |
| **Mots de passe** | **Vaultwarden** | **Coffre unique** + **2FA** + **emergency access** famille. |
### 9.2 L'accès distant (folzocorp.fr)
| Élément | Détail |
|---------|--------|
| **Domaine** | **folzocorp.fr** (principal) + **sous-domaines** par service |
| **Sous-domaines** | `cloud.folzocorp.fr` (Nextcloud) · `prisme.folzocorp.fr` (**PhotoPrism**) · `photos.folzocorp.fr` (**Synology Photos** — LAN-only, **temporaire**, disparaît avec le xpenology en Phase 6) · `media.folzocorp.fr` (Jellyfin) · `matrix.folzocorp.fr` (Matrix) · `git.folzocorp.fr` (Gitea) · `pass.folzocorp.fr` (Vaultwarden) · `n8n.folzocorp.fr` (n8n) · `ai.folzocorp.fr` (OpenWebUI) |
| **TLS** | **Caddy** génère + renouvelle **automatiquement** les certificats Let's Encrypt (pas de script). |
| **Exposition** | **Seulement** les services **nécessaires** à l'extérieur passent par Caddy. Le **reste** est **LAN-only** (accès via **WireGuard**). |
> **Principe** : **le moins d'exposition possible**. Par défaut **LAN-only** ; l'extérieur passe par **WireGuard** (VPN) ou **Caddy** (services explicitement exposés, TLS + 2FA).
### 9.3 Le firewall strict (J5040)
| Règle | Détail |
|-------|--------|
| **Par défaut** | **Dénier** tout (WAN → LAN). |
| **Autorisé WAN** | Seulement les ports **Caddy** (443) + **WireGuard** (UDP 51820). |
| **LAN** | Libre (les services sont LAN-first). |
| **Enfants** | **AdGuard Home** (DNS filtré) + **profils** (restriction par appareil). |
---
## S10 — Backup 3-2-1 (restic/borg + LUKS)
> **Statut** : ✅ **Tranché** (05/10/2026), **révisé 10/10/2026** (G9 : le disque source n'est pas LUKS — le chiffrement est assuré par **restic lui-même**) — **restic** (ou borg) **chiffré + append-only** + **procédure de restore testée**. Répond à l'**AC5**.
### 10.1 Pourquoi restic/borg (pas rsync)
| Critère | **restic / borg** ✅ | rsync ❌ |
|---------|----------------------|----------|
| **Déduplication** | ✅ (économe en espace) | ❌ |
| **Chiffrement** | ✅ (intégrée) | ❌ (à ajouter) |
| **Versioning** | ✅ (historique) | ❌ |
| **Append-only / anti-ransomware** | ✅ (snapshots non-modifiables) | ❌ |
| **Incidentel** | ✅ (seul les changements) | 🟡 (delta, mais pas versionné) |
> **Décision** : **restic** (ou **borg**) — **chiffré**, **dédupliqué**, **versionné**, **append-only** (résiste au ransomware). C'est la **pérennité** au sens fort.
### 10.2 Le schéma 3-2-1 (source unique : `DOSSIER-RECREATION.md` §R4)
> **Schéma des 3 copies** (originale G9 + PC IA / intermédiaire Freebox / offsite 218play) : **source unique** = `DOSSIER-RECREATION.md` §R4 (tableau complet : supports, machines, contenu, fréquence).
**Outil** : **restic** (ou borg) — **chiffré + append-only** (S10.1). Copie 2 (Freebox) = **quotidien**, copie 3 (218play) = **hebdo**.
> **État 10/10/2026 (copie 2, G9)** : ✅ **restic 0.19.1 + rclone 1.75.2**, repo
> `rclone:freeboxftp:Freebox/backup/g9` (FTP local de la Freebox, port **21**), snapshot
> initial **4.18 GiB**, **append-only prouvé**, **restore testée**, jobs cron
> 03:30 (backup, conteneurs stateful stoppés) / 04:00 (prune 7-4-12-5) / 09:15 (health
> + alerte Matrix). **Mont CIFS abandonné** (restic échoue sur `chmod`, FUSE perd des
> objets) → **backend rclone**, donc **aucune dépendance de montage** (résiste au
> reboot, pas besoin de `smbd` au boot).
>
> **Phase 5 (planifié, non réalisé)** : la Freebox **ne peut pas exécuter restic**
> (FTP/SFTP/SMB/WebDAV exposés, pas de conteneur pour rest-server, **autostart VM non
> validé**) → ① **VM Freebox** avec **`rest-server --append-only`** (repo append-only
> **côté serveur**, plus fort que l'actuel imposé par le rclone local du G9), servi en
> **HTTPS/TLS** + **`htpasswd`** (`g9-backup` en écriture, `g9-restore` en lecture), repo
> cible `rest:https://…` ;
> ② **`restic copy`** G9 → Freebox → **218play** (copie 3, repo append-only dédié,
> identifiants **`NoAccess`** côté SMB) ; ③ **chroot/rootfs durci** sur le G9 pour
> isoler le job de backup.
### 10.3 Les données IA dans le 3-2-1
| Donnée IA | Où | Sauvegardée ? |
|-----------|-----|---------------|
| **Qdrant** (vector DB / 2ᵉ cerveau) | PC IA | ✅ **Oui** (critique) |
| **n8n** (workflows) | G9 | ✅ **Oui** |
| **Vault second cerveau** (md) | Gitea (G9) | ✅ **Oui** (critique) |
| **hermes** (mémoire) | PC IA | ✅ **Oui** |
| **Modèles GGUF** (98 Go) | PC IA | ❌ **Non** (re-téléchargeables) |
| **Ollama** (modèles) | PC IA | ❌ **Non** (re-téléchargeables) |
### 10.4 La procédure de restore **testée** (AC5)
> **Un backup non testé = pas de backup.** La procédure est **documentée** et **testée au moins 1×/trimestre**.
| Étape | Action |
|-------|--------|
| 1 | **Restaurer** un snapshot restic sur une **machine de test** (G7). |
| 2 | **Vérifier** l'intégrité (photos, fichiers, mots de passe, données IA). |
| 3 | **Valider** que la famille **peut repartir** (services accessibles). |
| 4 | **Documenter** le résultat (date, durée, anomalies). |
> **Continuité** (si « il m'arrive quelque chose ») : la **famille sait restaurer** (testé 1×), les **mots de passe** ont un **emergency access**, la **doc** est lisible par un tiers.
---
## S11 — Ops (Compose + Gitea + Watchtower + Beszel)
> **Statut** : ✅ **Tranché** (05/10/2026) — **Docker Compose versionné dans Gitea** + **Watchtower** (MAJ **sélective** : stateless auto / stateful manuel) + **Beszel** (monitoring) + **n8n** (alertes). Pas de Portainer, pas de PaaS. *(Affiné 06/10/2026 après l'incident Nextcloud — voir §11.4.)*
### 11.1 L'approche ops (sobre, versionnée, observable)
| Brique | Rôle | Machine | Licence |
|--------|------|---------|---------|
| **Docker Compose** | **Déclaration** des services (fichiers `docker-compose.yml`) | toutes | Apache-2.0 |
| **Gitea** | **Versioning** des `docker-compose.yml` + config (source de vérité) | G9 | MIT |
| **Watchtower** | **Mises à jour** automatiques **sélectives** (stateless auto / stateful exclu + manuel) | J5040 + G9 + PC IA | Apache-2.0 |
| **Beszel** | **Monitoring** léger + historique + **alertes** (métriques + état conteneurs) | J5040 (hub) + agents | MIT |
| **Registre** (`11-registry.sh` → `REGISTRE-BRIQUES.md`) | **Inventaire généré** (images épinglées, labels, endpoints, état) + **détection de dérive** par `git diff` | pilot → .24/.27 (lecture seule) | MIT (kit) |
| **Sondes applicatives** (`12-probes.sh`) | **`up ≠ utilisable`** : sonde la **fonction** (occ status, discovery, healthz, login) + **alertes JSON** + **1 digest/jour** | G9 (cron) | MIT (kit) |
| **n8n** | **Alertes** + **automatisation** (workflows) | G9 | ⚠️ fair-code |
### 11.2 Pourquoi pas Portainer / PaaS
| Option | Verdict | Raison |
|--------|---------|--------|
| **Portainer** | ❌ | **Redondant** avec Compose + Gitea. Une brique de plus à maintenir. |
| **PaaS (ex. Coolify)** | ❌ | **Trop lourd** pour 4 machines. Compose + Gitea suffit. |
| **Compose + Gitea + Watchtower** | ✅ | **Sobre**, **versionné**, **reproductible**. C'est la **production**. |
### 11.3 Le flux ops (reproductible)
```
docker-compose.yml (source de vérité, dans Gitea)
│
▼
git pull → docker compose up -d (déploiement)
│
▼
Watchtower (MAJ images **stateless** uniquement — stateful exclu)
│
▼
Beszel (monitoring) → alertes → n8n → Matrix
```
> **Principe** : **tout est dans git** (les `docker-compose.yml` + config). Une machine tombe → on **re-crée** depuis Gitea en **< 5 min** (c'est la **maîtrise**, pilier 5).
### 11.4 Watchtower **sélectif** (règle stateless / stateful)
> **Contexte** : l'**incident Nextcloud** (06/10/2026 — voir `ETAT-DE-LART-2026-10-06.md` §3) a montré qu'un Watchtower **non sélectif** a mis à jour **l'application ET sa base MariaDB** la nuit, sans laisser la **migration de schéma** se terminer → Nextcloud en **maintenance mode** (503). **Watchtower ne « teste » rien** : il remplace l'image et relance le conteneur, point. La sécurité vient de la **sélectivité**, pas d'un test.
**La règle** :
| Type de conteneur | Traitement Watchtower | Pourquoi |
|-------------------|-----------------------|----------|
| **Stateless** (pas d'état persistant : Caddy, AdGuard, SearXNG, Beszel, n8n*…) | **Auto** (Watchtower les met à jour) | Pas d'état à migrer → le swap d'image est sûr. |
| **Stateful** (base de données, cache persistant, état : Nextcloud, MariaDB/Postgres, Redis, Vaultwarden, Gitea, InfluxDB, OnlyOffice/Collabora, Leantime, Affine, Joplin, Qdrant…) | **Exclu** (label `com.centurylinklabs.watchtower.enable=false`) + **MAJ manuelle** (§11.5) | Une MAJ d'image **sans migration de schéma** = **corruption / service HS**. La migration doit être **supervisée**, avec **backup en place**. |
> **\* n8n** : son **état** (workflows) est dans **Postgres** → le conteneur n8n est **stateless** (image), mais sa **DB** est **stateful** (exclue). On traite la **DB** comme stateful.
**Les briques à exclure de Watchtower (stateful, sur le NAS actuel + cible G9) :**
| Brique | Image | Pourquoi stateful |
|--------|-------|-------------------|
| **Nextcloud** | `nextcloud:latest` | App + migration de schéma (l'incident). |
| **MariaDB** (Nextcloud DB) | `mariadb:10.6` | Base de données — migration de schéma. |
| **Redis** (Nextcloud cache) | `redis:latest` | Cache persistant (RDB/AOF). |
| **Vaultwarden** | `vaultwarden/server:latest` | Coffre (Postgres interne). |
| **Gitea** | `gitea/gitea:latest` | Repos + DB (Postgres/SQLite). |
| **n8n** + **Postgres** | `n8n:latest` + `postgres:17` | Workflows + DB. |
| **InfluxDB** | `influxdb:2.7` | Base de métriques. |
| **OnlyOffice / Collabora** | `onlyoffice/documentserver:latest` | État + config persistante. |
| **Leantime** + **MySQL** | `leantime:latest` + `mysql:8.4` | App + DB. |
| **Affine** + **Postgres** + **Redis** | `affine:stable` + `pgvector:pg16` + `redis:latest` | App + DB + cache. |
| **Joplin** + **Postgres** | `joplin/server:latest` + `postgres:16` | App + DB. |
| **Qdrant** | `qdrant/qdrant:latest` | Vector DB (2ᵉ cerveau) — **critique**. |
**Configuration Watchtower cible (sur chaque machine)** :
```yaml
services:
watchtower:
image: containrrr/watchtower:1 # ⚠️ pin la MAJEURE (pas :latest)
container_name: watchtower
environment:
- TZ=Europe/Paris
- WATCHTOWER_SCHEDULE=0 0 2 * * * # fenêtre de MAJ (nuit)
- WATCHTOWER_CLEANUP=false # ⚠️ GARDER les anciennes images (rollback)
- WATCHTOWER_INCLUDE_STOPPED=false # ne pas toucher les conteneurs arrêtés
# Notifications (n8n / Matrix) — on est averti de chaque MAJ :
- WATCHTOWER_NOTIFICATIONS=matrix
- WATCHTOWER_NOTIFICATION_MATRIX_HOMESERVER=https://matrix.folzocorp.fr
- WATCHTOWER_NOTIFICATION_MATRIX_ROOMID=!SALON-OPS
# (ou WATCHTOWER_NOTIFICATIONS=n8n + URL du webhook)
volumes:
- /var/run/docker.sock:/var/run/docker.sock
restart: unless-stopped
```
> **Pinning des majeures** : les images stateless sont **pinées en majeure** (`:1`, `:2`…) pour éviter un saut mineur surprise ; les **stateful sont exclus** (pas de pinning — MAJ manuelle supervisée, §11.5).
>
> **⚠️ Écart actuel (NAS) = action corrective** : le Watchtower du NAS tourne avec **0 exclusion**, **0 notification**, `WATCHTOWER_CLEANUP=true` (supprime les anciennes images → **pas de rollback**), et l'image `:latest` (non pinnée). C'est **exactement** la config qui a causé l'incident Nextcloud. **Action immédiate** : exclure les briques stateful de Watchtower **sur le NAS actuel** (même **avant** la migration xpenology → G9) — voir S13.1 (A.0) + `DOSSIER-RECREATION.md` R7.
### 11.5 Procédure de MAJ **manuelle** des services **stateful**
> **Règle absolue** : **pas de MAJ stateful sans backup en place** (le 3-2-1 est fonctionnel, §S10). C'est la leçon de l'incident Nextcloud.
| Étape | Action | Détail |
|-------|--------|--------|
| **1** | **Backup** DB + config | `pg_dump` / `mysqldump` (ou snapshot restic) de la **base** + copie du **dossier de config** (ex. `nextcloud/config`). **Vérifier** que le dump est **complet** (taille, lignes). |
| **2** | **Maintenance mode ON** | `docker exec nextcloud_app php occ maintenance:mode --on` (ou équivalent). **Bloque** les écritures pendant la migration. |
| **3** | **Pull + up** | `docker compose pull <service>` puis `docker compose up -d <service>` (image **pinée** à la nouvelle version). |
| **4** | **Migration de schéma** | `docker exec nextcloud_app php occ upgrade` (laisse **terminer** — c'est l'étape que Watchtower a **sauté**). |
| **5** | **Vérification** | `status.php` (version, `needsDbUpgrade: false`, maintenance `false`) + `occ status` + test fonctionnel (login, 1 fichier). |
| **6** | **Maintenance mode OFF** | `docker exec nextcloud_app php occ maintenance:mode --off`. |
| **7** | **Alerte** | n8n → **Matrix** : « MAJ stateful <service> <vX> → <vY> OK » (ou échec → **rollback** depuis l'ancienne image, conservée car `CLEANUP=false`). |
> **Rollback** : si l'étape 5 échoue → `occ maintenance:mode --on` + restaurer le **dump** de l'étape 1 + relancer l'**ancienne** image (conservée). C'est la raison de `WATCHTOWER_CLEANUP=false` + du **pinning**.
---
## S12 — Enfants & MDM
> **Statut** : ✅ **Tranché** (05/10/2026) — **AdGuardHome** (DNS + parental) + **Google Family Link** (maintenant) + **MicroMDM / Android Enterprise** (option future).
### 12.1 La protection enfants (actuelle)
| Brique | Rôle | Machine |
|--------|------|---------|
| **AdGuard Home** | **DNS filtré** + **profils enfants** (restriction par appareil) | J5040 |
| **Google Family Link** | **Contrôle parental** (temps d'écran, apps) sur Android | (cloud Google, **usage parental** uniquement) |
> **Note honnêteté** : **Family Link** est un service **Google** (cloud). C'est le **seul** service GAFAM **gardé** — mais pour un **usage parental** (contrôle des enfants), pas pour les **données famille**. C'est **pragmatique** (pas d'alternative OSS MDM mature pour Android familial) et **limité** (pas de données familiales, juste du contrôle).
### 12.2 L'option future : MDM Android (si besoin)
| Option | Détail |
|--------|--------|
| **MicroMDM** | **MDM** iOS (Apple) — OSS. Si on a des **iPad/iPhone**. |
| **Android Enterprise** | **MDM** Android — via un **gestionnaire** (ex. **MicroMDM** équivalent Android, ou **Geeks**). **Option future** si le besoin de **contrôle à distance** des téléphones enfants se précise. |
> **Décision** : **Family Link** pour l'instant (simple, gratuit, parental). **MDM OSS** en **option future** si le besoin de **contrôle à distance** (rester, verrouiller, effacer) se précise. **Pas de sur-ingénierie** maintenant.
### 12.3 L'usage enfants (résilience = usage)
| Utilisateur | Appareil | Usage quotidien |
|-------------|----------|-----------------|
| **Enfants** | Téléphone Android + PC | **AdGuard** (DNS filtré) + **Family Link** (contrôle) + **Jellyfin** (contenus) + **PhotoPrism** (auto-upload) |
---
## S13 — Plan de migration R&D → production
> **Statut** : ✅ **Posé** (05/10/2026) — **phased**, avec **critères de succès** par phase. Répond à l'**AC7**. S'appuie sur les **phases R5** de `DOSSIER-RECREATION.md` (plan machine) ; cette section ajoute la **couche logicielle**.
### 13.0 Règle de lecture
- **R5 = plan machine** (fondations, cœur famille, finitions). **Cette section = couche logicielle** (quelle brique, dans quel ordre).
- **Fondations d'abord** : on ne déploie pas de brique sur un système **sans backup** (risque #1).
- **On ne passe à la phase N+1 qu'après validation de la phase N.**
- **Statut** : ⬜ à faire → 🟡 en cours → ✅ validé.
> **🔴 Prérequis absolu de TOUTE migration** : un **backup 3-2-1 fonctionnel** (restic/borg chiffré, **restauration testée**, données IA incluses — S10) **AVANT** toute migration (xpenology → G9, ou MAJ d'une brique stateful). **Aucune migration sans backup = aucun risque pris.** L'**incident Nextcloud** (06/10/2026) est la **preuve** que le risque « **MAJ stateful non supervisée** » est **réel** : Watchtower a mis à jour l'app + la DB sans laisser la migration de schéma se terminer → service HS. La **sélectivité** (S11.4) + la **procédure manuelle** (S11.5) + le **backup en place** sont la réponse.
> **🔴 Action corrective immédiate (sur le NAS actuel, AVANT la migration)** : **exclure les briques stateful de Watchtower** sur le xpenology (label `com.centurylinklabs.watchtower.enable=false` — liste S11.4) + passer `WATCHTOWER_CLEANUP=false` + notifier via n8n/Matrix. C'est **urgent** (le NAS actuel est toujours en production, sans exclusion) et **indépendant** de la migration xpenology → G9. → **Phase A.0** ci-dessous.
### 13.1 Phase A — Fondations logicielles (avec R5 Phase 0)
**Objectif** : l'**edge** + le **cœur** + le **bloc IA** en place, **backup 3-2-1 fonctionnel**.
| # | Action logicielle | Dépendance | Critère de succès (vérifiable) |
|---|-------------------|------------|--------------------------------|
| **A.0** | **Sécuriser le NAS actuel** : **exclure les briques stateful** de Watchtower (S11.4) + `WATCHTOWER_CLEANUP=false` + notifications n8n/Matrix + **backup 3-2-1 fonctionnel** (prérequis) | — | **0 stateful** sous Watchtower sur le NAS ; **backup 3-2-1 opérationnel** (restauration testée) ; **aucune MAJ stateful non supervisée** possible |
| A.1 | **J5040 edge** : firewall + DHCP + AdGuard + **SearXNG** + **Caddy** (TLS auto) + WireGuard | R5 0.3 | Edge fonctionnel ; certificats **auto-renew** ; sites accessibles ; firewall strict ; recherche locale fonctionnelle |
| A.2 | **G9 cœur** : OS + RAID1 + USB + **SMB** | R5 0.4 | G9 monté ; IP .25 ; partages SMB accessibles |
| A.3 | **PC IA** : **Ollama** (Qwen 3.8max) + **Qdrant** + **hermes** + **OpenWebUI** (1 seul) | R5 0.5 | LLM fonctionnel ; conso idle mesurée < 80 W ; J5040 < 30% |
| A.4 | **Backup 3-2-1** : **restic** (G9+PC IA → Freebox quotidien → 218play hebdo) + **LUKS** | R5 0.6 | 3 copies en place + **restauration testée** (données IA incluses) |
| A.5 | **Ops** : **Compose** dans **Gitea** + **Watchtower** + **Beszel** | A.1–A.4 | Tous les services déclarés en Compose ; MAJ auto ; monitoring + alertes |
**Statut** : ⬜
**Dépendances** : R5 Phase 0
### 13.2 Phase B — Cœur famille (dégafamisation, avec R5 Phase 1)
**Objectif** : le **G9** devient le **cœur famille** (les briques famille en place).
| # | Action logicielle | Dépendance | Critère de succès |
|---|-------------------|------------|-------------------|
| B.1 | **PhotoPrism** (photos, in-place) + migration 10 ans | Phase A + R5 1.1 | Photos accessibles, IA OK, auto-upload Android |
| B.2 | **Nextcloud** (Drive + Collabora + Groupware + Deck + Notes) | Phase A | Fichiers + Office + agenda + contacts + tâches accessibles |
| B.3 | **Vaultwarden** (mots de passe) + 2FA + emergency access | Phase A | Coffre accessible famille, 2FA actif |
| B.4 | **Jellyfin** (vidéo+musique) + **\*arr** + **qBittorrent** | Phase A | Films/séries/musique accessibles |
| B.5 | **Gitea** (vault second cerveau) + **Obsidian** | Phase A | Vault versionné, accessible |
| B.6 | **n8n** (automatisation + alertes → Matrix) | Phase A | Workflows fonctionnels, alertes en Matrix |
| B.7 | **DNS** (AdGuard) + **sous-domaines** folzocorp.fr | Phase A | Sous-domaines résolus, TLS auto |
**Statut** : ⬜
**Dépendances** : Phase A + R5 Phase 1
### 13.3 Phase C — Finitions (dégafamisation complète, avec R5 Phase 2)
**Objectif** : la famille **n'utilise plus de GAFAM** (sauf Family Link parental).
| # | Action logicielle | Dépendance | Critère de succès |
|---|-------------------|------------|-------------------|
| C.1 | **Matrix + Jitsi + Element** (complément du foyer, **pas** un remplacement de WhatsApp) | Phase B | Famille messagerie + visio en local |
| C.2 | **Home Assistant** (enceintes Google) + **Frigate** (caméras) | Phase B | Assistant vocal + vision caméras |
| C.3 | **Bot hermes ↔ Matrix** (Effi famille) | Phase B + 2ᵉ cerveau | Effi répond dans Matrix |
| C.4 | **Enfants** : AdGuard profils + Family Link | Phase B | Enfants protégés (DNS + parental) |
| C.5 | **Décommissionner** le ballast R&D (Dify, RAGFlow, conteneurs morts…) | Phase B | ~70 conteneurs → ~20 briques ; plus de dupliqué |
| C.6 | **Valheim** (jeu famille) | Phase B | Monde accessible |
**Statut** : ⬜
**Dépendances** : Phase B + R5 Phase 2
### 13.4 Vue d'ensemble
```
Phase A (Fondations logicielles) ──► Phase B (Cœur famille) ──► Phase C (Finitions)
edge + cœur + IA + 3-2-1 + ops PhotoPrism + NC + Jellyfin Matrix + HA +
(avec R5 Ph0) + Vaultwarden + Gitea + n8n enfants + décommission
(avec R5 Ph1) (avec R5 Ph2)
```
> **Lien avec R5** : R5 = **machine** (fondations, cœur, finitions). Cette section = **logiciel** (les briques, dans l'ordre). **Un seul plan, deux couches** (comme le guide culture, C1-C5).
---
## S14 — Grille des décisions + recommandations
> **Statut** : ✅ **Tranchées** (05/10/2026) — chaque décision a une **grille d'évaluation remplie** + une **recommandation**. Répond à l'**AC9**.
### 14.1 Photos (R6.1)
| Critère | PhotoPrism ✅ | Immich | Nextcloud Photos |
|---------|---------------|--------|------------------|
| Lecture in-place | ✅ | ❌ (importe) | 🟡 |
| IA (visages, sémantique) | ✅ | ✅ | ❌ |
| Partage famille | ✅ | ✅ | ✅ |
| Auto-upload Android | ✅ | ✅ | 🟡 |
| Sobriété (G9 16 Go) | ✅ | 🟡 | ✅ |
| Licence | AGPL-3.0 | AGPL-3.0 | AGPL-3.0 |
| Sortie | ✅ (originaux intacts) | 🟡 | ✅ |
| **Verdict** | **✅ Recommandé** | ❌ (désorganise) | ❌ (pas d'IA) |
> **Recommandation** : **PhotoPrism** (lecture in-place + IA + sobre).
### 14.2 Notes / second cerveau (R6.2)
| Critère | Obsidian+Gitea+Qdrant ✅ | Nextcloud Notes | Joplin | Affine |
|---------|--------------------------|-----------------|--------|--------|
| Versioning | ✅ (git) | ❌ | 🟡 | 🟡 |
| Structure liée (wikilinks) | ✅ | ❌ | 🟡 | ✅ |
| Lisible par l'IA (RAG) | ✅ (md + Qdrant) | 🟡 | 🟡 | ❌ |
| Format ouvert | ✅ (md) | 🟡 | ✅ | 🟡 |
| Échelle (une vie) | ✅ | ❌ | 🟡 | 🟡 |
| **Verdict** | **✅ Recommandé** | ❌ (mauvais fit store) | ❌ (silo) | ❌ (R&D) |
> **Recommandation** : **Obsidian** (viewer) + **Gitea** (store) + **Qdrant** (index) pour le **second cerveau** ; **Nextcloud Notes** pour les **notes rapides famille**.
### 14.3 Mail
| Critère | Nextcloud Mail (IMAP) ✅ | Serveur SMTP local |
|---------|--------------------------|--------------------|
| Fiabilité livraison | ✅ (Gmail/Hotmail) | ❌ (SPF/DKIM/DMARC, spam) |
| Complexité | ✅ (faible) | ❌ (élevée) |
| Pérennité | ✅ | 🟡 (risque spam) |
| **Verdict** | **✅ Recommandé** | ❌ (trop risqué en prod) |
> **Recommandation** : **Nextcloud Mail** (lecture IMAP) + **livraison externe** (Gmail/Hotmail). Dégafamisation complète du mail = **horizon > 1 an**.
### 14.4 Frontend IA
| Critère | OpenWebUI (1 seul) ✅ | Dify | mcpo+pipelines |
|---------|----------------------|------|----------------|
| Sobriété | ✅ | ❌ (14 conteneurs) | 🟡 |
| Simplicité famille | ✅ | 🟡 | ❌ |
| Pérennité | ✅ | 🟡 (R&D) | 🟡 |
| **Verdict** | **✅ Recommandé** | ❌ | ❌ |
> **Recommandation** : **1 seul OpenWebUI** (front famille) + **hermes** (harnais agent).
### 14.5 Communication (Matrix)
| Critère | Matrix+Jitsi+Element ✅ | WhatsApp | Signal |
|---------|------------------------|----------|--------|
| OSS / souverain | ✅ | ❌ | ✅ |
| Visio intégrée | ✅ (Jitsi) | ✅ | 🟡 |
| Fédéré / auto-hébergé | ✅ | ❌ | 🟡 |
| **Verdict** | **✅ Recommandé** | ❌ (GAFAM) | 🟡 (pas d'auto-hébergement facile) |
> **Recommandation** : **Matrix (Synapse) + Jitsi + Element** en **complément du foyer** (messagerie familiale + alertes + assistant). **Révisé 12/10/2026** : WhatsApp **n'est pas remplaçable** dans notre usage (famille, amis, travail) → il reste la messagerie principale ; Element couvre le **foyer** et le **canal d'alerte**. Le pont `mautrix-whatsapp` est **étudié, non déployé** : numéro familial **interdit**, risque de bannissement, coût de session (QR / 12 jours). Détail : `g9-migration/BRIDGE-WHATSAPP.md`.
### 14.6 MDM enfants
| Critère | Family Link ✅ (maintenant) | MicroMDM / Android Enterprise (future) |
|---------|------------------------------|----------------------------------------|
| Simplicité | ✅ | 🟡 |
| OSS | ❌ (Google) | ✅ |
| Contrôle parental | ✅ | ✅ |
| **Verdict** | **✅ Recommandé (maintenant)** | 🟡 (option future) |
> **Recommandation** : **Google Family Link** (maintenant, usage parental) + **MDM OSS** (MicroMDM/Android Enterprise) en **option future**.
### 14.7 Coffre famille (décision 12/10/2026)
| Critère | **Vaultwarden unique (6 personnes)** ✅ | Nextcloud Passwords |
|---------|----------------------------------------|---------------------|
| Dépendance | ✅ indépendant des autres briques | ❌ le coffre vit dans la brique qu'il protège (Nextcloud HS = plus les accès pour réparer Nextcloud) |
| Reset admin d'un compte enfant | ✅ sans effet sur le coffre | ❌ clés dérivées du mot de passe → coffre potentiellement illisible |
| Modèle familial (organisations, emergency access) | ✅ | ❌ |
| Coût pour 6 (import, backup, reset, formation) | ✅ 1 chemin | ❌ 2 chemins (registre doublé) |
| **Verdict** | **✅ Retenu** | ❌ Non retenu (pilote adulte possible, non déclenché) |
### 14.8 Identité (décision 12/10/2026, ordre validé)
| Étape | Décision | Statut |
|---|---|---|
| 1 | **Registre d'identités** (moitié générée + moitié humaine) — répond à « quel compte a servi ? » | ✅ posé (`g9-migration/REGISTRE-IDENTITES.md`) |
| 2 | **Étude exposition internet** avant tout IdP | ✅ étude écrite, 5 décisions à rendre |
| 3 | **Authelia** en cible, pilote 3 briques (Synapse, Gitea, Jellyfin), **opt-in + break-glass** | 🟡 après étude + Phase 5 |
| — | Authentik / Keycloak / Samba AD / FreeIPA / Nextcloud-IdP | ❌ écartés (poids, sur-ingénierie, SPOF sur la brique la plus stateful) |
### 14.9 Suivi applicatif (décision 12/10/2026)
| Critère | **Sondes + registre + Diun** ✅ | Grafana/Prometheus (+cAdvisor) | Netdata | Uptime Kuma |
|---|---|---|---|---|
| Couvre `up ≠ utilisable` | ✅ (occ, discovery, healthz, login) | ❌ (métriques) | 🟡 | ✅ |
| Briques ajoutées | **0** (scripts du kit) | 4 | 1 (lourd) | 1 (stateful) |
| Chevauchement avec Beszel | **complémentaire** | redondant (InfluxDB déjà écarté) | redondant | partiel |
| Charge de maintenance | faible (cron + 1 digest/jour) | élevée | moyenne | moyenne + fatigue d'alertes |
| **Verdict** | **✅ Retenu** | ❌ | ❌ | 🟡 reporté (déclencheur écrit, Phase 6 + 2 semaines d'usage) |
### 14.10 Autonomie de l'assistante IA (décision 12/10/2026)
> **Paliers G11** : L0 lecture seule → L1 propose → L2 exécute le **stateless documenté** → L3 stateful **sur GO explicite**. Portes chiffrées (≥ 90 % de propositions pertinentes sur 30 jours ; sinistre simulé sans perte). Interdits permanents : destructif, suppression de données, réseau (G6), wipe, création de privilège, lecture de secrets hors coffre. Détail : `g9-migration/README.md` (charte G11).
---
## S15 — Critères d'acceptance (AC1–AC10)
> **Statut** : ✅ **Tous remplis** par ce dossier. C'est la **preuve** que la table rase est **complète**.
| AC | Critère | Où c'est rempli |
|----|---------|-----------------|
| **AC1** | Chaque besoin famille/perso mappé sur **UNE brique + UNE machine** (pas d'orphelin, pas de doublon) | **S3.1** (tableau 28 briques, 1 besoin = 1 brique = 1 machine — **F9 recherche web = SearXNG** (S3.1 #28) ; **F15 RSS = suppression explicite** (S3.2, chemin de ré-add documenté)) + **S2.2** (rôle par machine) |
| **AC2** | Stack consolidée **≤ ~20 briques** + **liste de suppression explicite** | **S3.1** (~20 briques) + **S3.2** (liste de suppression : Dify, RAGFlow, STT/OCR dupliqués, conteneurs morts, OpenWebUI multiples → 1 seul) |
| **AC3** | Chaque outil **justifié** (maturité, maintenance, ressource, licence OSS, chemin de sortie) | **S3.1** (colonnes licence + sortie) + **S3.3** (justification détaillée par brique) |
| **AC4** | **Budget ressource** par machine tenable (J5040 ~7-9/16, G9 ~8-11/16, PC IA ~53/62, Freebox léger) | **S2.4** (tableau budget ressource par machine) |
| **AC5** | **3-2-1** avec **restic/borg** (chiffré, append-only) + **procédure de restore testée** (LUKS source abandonné 10/10/2026 — chiffrement porté par restic) | **S10** (restic/borg + procédure de restore testée §10.4) |
| **AC6** | Modèle **sécurité** (Caddy+TLS auto, WireGuard, firewall strict, copies chiffrées, 2FA, sous-domaines folzocorp.fr) | **S9** (modèle de sécurité couche par couche + sous-domaines §9.2) |
| **AC7** | **Plan de migration** R&D→production, **phased**, avec **critères de succès** par phase | **S13** (Phase A/B/C, critères de succès par action) |
| **AC8** | **Résilience/adoption** — chaque service a un **utilisateur nommé + appareil + usage quotidien** | **S3.4** (briques edge & infra) + **S5.3, S6.4, S7.3, S8.2, S12.3** (tableaux d'usage par utilisateur/appareil/usage) |
| **AC9** | **Décisions** (photos, sync notes, mail, frontend IA, Matrix, MDM) = **grille d'évaluation remplie + recommandation** | **S14** (6 grilles d'évaluation + recommandations) |
| **AC10** | **100% open source**, **licence notée par service** | **S3.1** (colonne licence par brique) + **S3.1 note** (honnêteté : n8n = fair-code, non-OSI, noté) |
> **Bilan** : les **10 critères** sont **tous remplis** par ce dossier. La **table rase** est **complète** : architecture ciblée, décisions tranchées, plan de migration posé, licences notées, budget ressource validé, sécurité + backup + ops + enfants couverts.
---
## Changelog
| Date | Version | Changement |
|------|---------|------------|
| 12/10/2026 | **v1.8** | **Identités mesurées + trou Synapse réparé + exposition durcie** : balayage lecture seule (`15-`/`16-identity-sweep`) → **Gitea 2FA = 0/4 et le bot `g9ops` est admin**, **Synapse admin = 0**, Nextcloud 8 comptes + providers 2FA installés, n8n 1 owner, PhotoPrism 3 comptes, **CouchDB = 401 (faux positif « sans auth » corrigé)** ; **1ᵉʳ admin Synapse créé et vérifié** (`26-synapse-admin-repair.sh` : `register` → mxid aléatoire `password_hash` NULL, **`HMAC incorrect`** sur la voie signée, puis **bcrypt en base + `docker restart` + `PUT /_synapse/admin/v2/users`** → login **OK** + API admin **OK** ; snapshot sqlite avant, compte temporaire désactivé, 0 purge ; `27-synapse-family-users.sh` outille les 6 comptes famille `admin:false`) ; **pare-feu durci sur GO** : SSH **LAN-only sur .24 et .27**, **443 LAN-only sur .24**, **plus aucune règle `Anywhere`** sur le G9, Tailscale coupé sur le pilot ; **dumps logiques** des 3 bases dans le périmètre restic + **rejouabilité Gitea prouvée** (116 tables) ; **hub Beszel hors-G9** sur J5040 (digest, ufw LAN-only, 200) ; **31 critères clôturés côté IA** avec distinction explicite « prouvé par mesure » / « geste humain » (`RESTE-HUMAIN.md`). Artéfacts : `scripts/{25,26,27}-*.sh`, §7 et §7.1 de `REGISTRE-IDENTITES.md`, `RUNBOOKS/matrix.md` réécrit. |
| 12/10/2026 | **v1.7** | **Mesures Phase 4.5 (l'existant est maintenant prouvé, pas seulement décidé)** : registre **22 conteneurs / 7 constats** et définitions compose **entrées dans le dépôt** (`matrix/`, `g9-queue/`, `valheim/`, `diun/` vivaient hors git) ; **dérive prouvée de bout en bout** (`--check --alert` → payload JSON reçu → revert → « aucune dérive ») ; **chaîne d'alerte vérifiée** : 5 payloads JSON conformes dans le salon ops + 3 notifications types avec event_ids (backup OK, backup KO provoqué, sonde KO) ; **Diun déployé** (digest `crazymax/diun@sha256:e324b793…`, notifie sans appliquer, `docker inspect` avant/après identique) ; **`prisme.folzocorp.fr` = 200** (route posée sur le J5040, Let's Encrypt DNS-01) — `photos.` sert encore PhotoPrism, web DSM `.25` = 000 ; **backup** : 5 snapshots Freebox, coffres + `gitea/db` + `nextcloud/db` + **505 836 entrées photos** dans le snapshot, **restauration sha256 identique à `.25`**, médias 15 To/5,5 To exclus par construction ; **photos** : 433 941 fichiers == 433 941, indexation 9,1 %, RAM 1,1 GiB. Artéfacts : `PHOTOS-DOUBLE-RUN.md`, `scripts/13-diun-notify.sh`, `scripts/g9-verify-alert.py --list`. |
| 12/10/2026 | **v1.6** | **Identité + suivi applicatif + communication (décisions 12/10)** : **S8 révisé** — Matrix/Jitsi/Element = **complément du foyer**, **pas** remplacement de WhatsApp (Element : 2 adultes d'abord, ados phase 2) ; **S9.2** sous-domaines alignés sur le réel (`pass.folzocorp.fr` = Vaultwarden, **`prisme.folzocorp.fr` = PhotoPrism**, `photos.folzocorp.fr` = Synology Photos **temporaire**, meurt Phase 6) ; **S11** enrichi de deux briques d'ops sans conteneur de plus : **registre généré** (`11-registry.sh` → `REGISTRE-BRIQUES.md`, dérive par `git diff`) et **sondes applicatives** (`12-probes.sh`, `up ≠ utilisable`, alertes **JSON** + 1 digest/jour) ; **S14.7→S14.10** : coffre **unique Vaultwarden** pour 6 (Nextcloud Passwords écarté : boucle de verrouillage + reset admin + pas d'emergency access), identité = **registre → étude exposition → Authelia** (Authentik/Keycloak/Samba AD/FreeIPA écartés), suivi = **sondes + registre + Diun** (Grafana/Prometheus/Netdata écartés, Uptime Kuma reporté avec déclencheur écrit), **G11 paliers d'autonomie IA**. Artéfacts : `g9-migration/{REGISTRE-IDENTITES,REGISTRE-BRIQUES,PARTAGE-SECRET-MAITRE,RESTORE-NAS-USB,EXPOSITION-INTERNET,BRIDGE-WHATSAPP}.md`, `RUNBOOKS/` ×7, charte **G11**. |
| 10/10/2026 | **v1.5** | **S10.2 — copie 2 (Freebox) EN PLACE sur le G9** : restic 0.19.1 + rclone 1.75.2, repo `rclone:freeboxftp:Freebox/backup/g9` (FTP local 21), snapshot 4.18 GiB, **append-only prouvé**, **restore testée** (sha256), cron 03:30/04:00/09:15 + alerte Matrix ; **mont CIFS abandonné** (restic/`chmod`, FUSE) → backend rclone, **persistance post-reboot sans montage**. **Phase 5 planifiée** (non réalisée) : VM Freebox + `rest-server --append-only` (autostart à valider), `restic copy` → 218play, identifiants `NoAccess`, chroot durci. |
| 06/10/2026 | **v1.4** | **Cohérence inter-dossiers (source unique)** : (1) **S10.2** — le schéma 3-2-1 ne **re-déclare plus** le tableau → **pointeur** vers `DOSSIER-RECREATION.md` §R4 (source unique) + note outil (restic, quotidien/hebdo) ; (2) **S4.3** — le modèle 2 couches ne **re-déclare plus** le principe → **pointeur** vers `PROJET-SECOND-CERVEAU.md` S4.1 (source unique) + tableau **mapping briques/machines** (spécificité du dossier logiciel) ; (3) **S3.1** — le tableau est **cadré autour des briques fonctionnelles** : la stack \*arr #10 = **1 brique**, les apps Nextcloud 13-15 marquées **↳ apps du socle NC #12** ; note de comptage précisée (**28 lignes = 25 briques fonctionnelles**, dans la cible ≤ ~20 briques de consolidation). |
| 06/10/2026 | **v1.3** | **Correction mainteneur hermes** : S3.1 #24 — « maintenu (Nous Research) » → « **maintenu (nesquena — `ghcr.io/nesquena/hermes-webui`)** », aligné sur l'image réellement en production (snapshot `ETAT-DE-LART-2026-09-30.md` §2.1). |
| 06/10/2026 | **v1.2** | **S11 Ops — Watchtower sélectif** (après l'**incident Nextcloud** du 06/10, documenté dans `ETAT-DE-LART-2026-10-06.md` §3) : correction de la règle **stateless = auto / stateful = exclu + MAJ manuelle** (S11.4) — suppression de l'adjectif « testées » (Watchtower ne teste rien) ; **liste des briques stateful à exclure** (Nextcloud, MariaDB, Redis, Vaultwarden, Gitea, n8n+Postgres, InfluxDB, OnlyOffice/Collabora, Leantime+MySQL, Affine+Postgres+Redis, Joplin+Postgres, Qdrant) ; config Watchtower cible (**pinning des majeures**, `CLEANUP=false`, notifications n8n/Matrix) ; **écart actuel NAS** (0 exclusion, 0 notification, `CLEANUP=true`, `:latest`) = action corrective. **Nouvelle procédure de MAJ manuelle stateful** (S11.5, 7 étapes + rollback, règle « pas de MAJ stateful sans backup »). **S13** : prérequis absolu « backup 3-2-1 fonctionnel AVANT toute migration » + **action corrective immédiate** (exclure les stateful de Watchtower sur le NAS actuel) + **Phase A.0** (sécuriser le NAS + backup). S11 statut + cohérence interne vérifiés. |
| 06/10/2026 | **v1.1** | **Correction AC1** (besoins orphelins) : **SearXNG** mappé dans la stack consolidée (S3.1 #28, edge J5040 — S2.2, S2.4, S3.4, S13 A.1) ; **FreshRSS** ajouté à la liste de suppression explicite (S3.2 — pas d'usage quotidien nommé, podcasts RSS couverts côté client par AntennaPod, chemin de ré-add documenté). S15 (AC1/AC8) mis à jour. |
| 05/10/2026 | **v1.0** | **Création du dossier Partie 5 (couche logicielle)** — table rase : 6 principes (S1), architecture cible **Option A** (S2, PC IA garde la RAM, Matrix+Jitsi sur J5040, HA sur Freebox), **stack consolidée ~20 briques** (S3) + **liste de suppression** (Dify, RAGFlow, dupliqués, morts), **bloc IA** (S4, Ollama+Qwen 3.8max+Qdrant+hermes+OpenWebUI), **PhotoPrism** (S5), **Nextcloud** socle (S6), **Jellyfin+\*arr+AntennaPod** (S7), **Matrix+Jitsi+Element** (S8), **sécurité** (S9, Caddy+WireGuard+LUKS+2FA+sous-domaines), **backup 3-2-1 restic/borg** (S10), **ops** (S11, Compose+Gitea+Watchtower+Beszel), **enfants/MDM** (S12), **plan de migration A/B/C** (S13), **grille des décisions** (S14), **AC1–AC10** (S15). Licences notées par brique (honnêteté : n8n = fair-code). |