# VPS memory-node — Objectif A : nœud mémoire persistante (10/07/2026) **Statut** : en production. Le VPS Contabo (`contabo-vps-qbt`, tailnet 100.94.90.119) réplique en continu la mémoire du NAS : miroir git `nas-runbooks`, données NyoraNotes et context-hub, avec snapshots restic versionnés. ## Architecture — PULL depuis le VPS (pas push depuis le NAS) Choix imposé par deux constats du 10/07 : 1. Pas de root/cron utilisable sur le NAS (mot de passe sudo de Best0f périmé dans la mémoire Claude). 2. **NAS→VPS port 22 KO par le tailnet** (timeout), alors que VPS→NAS fonctionne. Cause : Tailscale Synology en mode userspace. Conséquence jour J : le « delta final NAS→VPS » se fera en **pull depuis le VPS**. Tout tourne donc sur le VPS, user **`claude-oversight`** (cron) : | Quoi | Script | Cadence | |---|---|---| | Miroir git + rsync données | `/opt/memory-node/bin/memory-sync.sh` | horaire (h+17) | | Snapshot restic | `/opt/memory-node/bin/backup-push.sh` | quotidien 03:30 | | Vérif intégrité + restauration test | `/opt/memory-node/bin/backup-verify.sh` | hebdo dim. 04:00 | Échec de job → alerte Telegram (bot hermes-perso → Nabil) via `notify-telegram.sh`. ## Contenu répliqué - `/opt/memory-node/git/nas-runbooks.git` : miroir bare, pull horaire depuis Gitea (`100.86.197.88:3232`, token Gitea lecture `vps-memory-node-mirror`, credentials dans la config du remote, home 700). - `/opt/memory-node/data/nyora-notes/` et `data/context-hub/` : rsync `--delete` depuis `/volume1/docker/…`. - **Exclusions délibérées** : `.env`, `*.bak`, `@eaDir`, `.DS_Store` — aucun secret répliqué sur le VPS ; les `.env` se récupèrent via le backup USB. - Snapshots restic : `/opt/restic-repo` (rétention 14 j + 8 sem., `forget --prune` à chaque push). ## Mot de passe restic — emplacements (jamais dans ce repo) - **Maître** : NAS `/volume1/docker/scripts/.restic-password` (chmod 600, Best0f). - **Copie runtime** : VPS `/opt/memory-node/.restic-pass` (chmod 600, claude-oversight) — nécessaire car restic s'exécute sur le VPS. - Les deux fichiers contiennent la même valeur. Si rotation : regénérer sur le NAS, recopier sur le VPS, `restic init` d'un nouveau repo (l'ancien devient illisible). ## Accès VPS - **Tailscale SSH uniquement** (port 22 tailnet ; 22 public filtré par ufw, 2222/22222 fermés). `root` = mode `check` (ré-auth web périodique) ; `claude-oversight` = accept. - `claude-oversight` : **sudoers scopé** (`/etc/sudoers.d/claude-oversight`) — start/stop/restart de qbittorrent-nox, docker, tailscaled + journalctl/status. PAS de NOPASSWD:ALL. - Connexion interactive claude-oversight → alerte Telegram (`/etc/profile.d/claude-oversight-login-alert.sh`). - Docker 29 + compose v5 installés (prérequis doublure jour J), aucun conteneur lancé. ## Accès NAS depuis le VPS (le seul sens qui marche) Clé `id_ed25519` de claude-oversight autorisée pour Best0f (port 22222) mais **bridée par forced-command** `~/.ssh/vps-memory-pull.sh` : - source exigée 127.0.0.1 (= proxy userspace Tailscale ; un `from="100.94.90.119"` classique ne marche PAS, le NAS voit 127.0.0.1) ; - seule commande admise : `rsync --server --sender` (lecture seule) sur `nyora-notes/` et `context-hub/`. ## Vérifications rapides ```bash ssh claude-oversight@100.94.90.119 # depuis le Mac (tailnet) tail /opt/memory-node/log/memory-sync.log # rc=0 attendu restic -r /opt/restic-repo --password-file /opt/memory-node/.restic-pass snapshots --compact git -C /opt/memory-node/git/nas-runbooks.git log --oneline -1 # doit suivre Gitea à 1 h près ``` ## Restauration (perte du NAS) 1. `git clone /opt/memory-node/git/nas-runbooks.git` → savoir complet. 2. `restic restore latest --target /tmp/r` → données NyoraNotes/context-hub datées. 3. Relancer les services sur le VPS avec ces données (Docker déjà prêt). ## Reste à faire (hors Objectif A) - Renommer le nœud tailnet NAS `ahmed---yesmine` → `nas` (console admin Tailscale, ou sudo NAS avec le mot de passe actuel). - Mot de passe sudo Best0f à remettre à jour dans la mémoire Claude (celui connu est périmé).