nas-runbooks/common/RUNBOOK-HERMES-UPDATE.md

6.9 KiB

RUNBOOK — Mise à jour des 3 instances Hermes (NAS DS920+)

Dernière opération : 2026-06-15 Opérateur : Claude Code (via SSH Best0f@192.168.100.33:22222) Périmètre : hermes-tt, hermes-nyora, hermes-perso

Architecture réelle (IMPORTANT)

Les 6 conteneurs (3 agents + 3 workspaces) sont pilotés par UN SEUL compose : /volume1/docker/hermes-platform/docker-compose.yml (projet Docker hermes-platform). Des docker-compose.yml existent AUSSI dans chaque sous-dossier hermes-<i>/ mais ils ne sont PAS utilisés par le runtime (voir « Ce qui NE fonctionne PAS »). Vérifier la provenance via : docker inspect <c> --format "{{index .Config.Labels \"com.docker.compose.project.config_files\"}}"

Règle IP

  • SSH depuis le Mac : 192.168.100.33:22222
  • curl/git exécutés via SSH sur le NAS : 127.0.0.1
  • Depuis lintérieur dun container : 172.17.0.1
  • UID/GID volumes data/ : 1026:100 (obligatoire, sinon PermissionError — cf RUNBOOK-HERMES-UID)

Images avant → après (2026-06-15)

Instance Conteneur Image Avant Après
tt hermes-agent-tt nousresearch/hermes-agent:latest 882e06b1ad23 (build 14/06 22:07) 4d326de7174f (build 15/06 18:03)
nyora hermes-agent-nyora nousresearch/hermes-agent:latest 882e06b1ad23 4d326de7174f
perso hermes-agent-perso nousresearch/hermes-agent:latest 882e06b1ad23 4d326de7174f
tt hermes-workspace-tt ghcr.io/outsourc-e/hermes-workspace:latest ac411feadfe5 (08/05) ac411feadfe5 (inchangé — pas de MAJ)
nyora hermes-workspace-nyora ghcr.io/outsourc-e/hermes-workspace:latest ac411feadfe5 ac411feadfe5 (inchangé)
perso hermes-workspace-perso ghcr.io/outsourc-e/hermes-workspace:latest ac411feadfe5 ac411feadfe5 (inchangé)

Digest agent après : nousresearch/hermes-agent@sha256:474477ad6066d1acc4ca3ae870302568ec3bc6772d12e554f150822f33475f0f

Résultat : seuls les 3 AGENTS avaient une image plus récente. Les 3 workspaces nont PAS été recreate (image identique → rien à mettre à jour).

Anomalie corrigée

Avant : lagent perso tournait sous le nom b7f6e6ac8bbf_hermes-agent-perso (collision de nom héritée dun docker compose up lancé dans le sous-dossier perso). Le compose up --force-recreate hermes-agent-perso depuis le compose RACINE a réclamé le nom propre hermes-agent-perso. Anomalie éliminée (plus aucun conteneur à préfixe hash).

Commandes exactes utilisées (via SSH, 127.0.0.1)

D=/usr/local/bin/docker
cd /volume1/docker/hermes-platform

# 1. Pull (service par service, mais image agent partagée par les 3)
$D compose pull hermes-agent-tt hermes-workspace-tt
# Comparer digest avant/après — ne recreate que si plus récent

# 2. Backup data/ (point de rollback)
TS=$(date +%Y%m%d_%H%M%S)
for i in tt nyora perso; do cp -r hermes-$i/data hermes-$i/data.bak_$TS; done

# 3. Supprimer les locks Telegram (sinon "token already in use")
find /volume1/docker/hermes-platform -name "telegram-bot-token-*.lock" -delete

# 4. Recreate AGENT par AGENT (jamais simultané), healthy avant le suivant
for i in tt nyora perso; do
  $D compose up -d --force-recreate hermes-agent-$i
  sleep 40
  stat -c "%u:%g" hermes-$i/data        # DOIT = 1026:100
  $D inspect hermes-agent-$i --format "{{.State.Health.Status}}"  # DOIT = healthy
done

# 5. Vérif UI
for p in 3010 3020 3030; do curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:$p/; done

Backup de cette opération : data.bak_20260615_191734 (dans chaque hermes-/).

Ce qui NE fonctionne PAS (pièges rencontrés)

  • NE PAS lancer docker compose up dans un sous-dossier hermes-<i>/ : les compose par instance réutilisent les MÊMES container_name → collision → conteneur renommé avec préfixe hash (b7f6e6ac8bbf_...). Toujours utiliser le compose RACINE.
  • git absent du host DSM ET des containers (linux-mcp-nas) : pour committer un runbook, utiliser lAPI Gitea (PUT/POST /api/v1/repos/bolbol//contents/...) en basic auth bolbol, PAS git push.
  • Les workspaces navaient pas de nouvelle image : les recreate aurait été inutile (interruption sans gain). Toujours comparer les digests avant de recreate.
  • Le find ... -delete des locks balaie aussi les data.bak_* : sans conséquence (les locks seraient supprimés au rollback de toute façon).

Procédure de ROLLBACK (par instance)

D=/usr/local/bin/docker
cd /volume1/docker/hermes-platform
$D compose stop hermes-agent-<inst>
rm -rf hermes-<inst>/data && mv hermes-<inst>/data.bak_20260615_191734 hermes-<inst>/data
chown -R 1026:100 hermes-<inst>/data
# Repointer sur lancienne image si besoin : retag 882e06b1ad23 en :latest
# $D tag 882e06b1ad23 nousresearch/hermes-agent:latest
$D compose up -d --force-recreate hermes-agent-<inst>

Hardening 2026-06-15 (suite MAJ)

Audit post-MAJ + corrections. Config STAGED, sans recreate : les blocs 3,4,6,7,9 prennent effet au prochain docker compose up -d --force-recreate (agent par agent). Les conteneurs ont continue de tourner sur l ancienne config pendant l operation.

Bloc Action Ou / commit
1 Compose par instance + .env instances neutralises (.disabled) mv local ; rename API Gitea hermes-nyora/perso (tt absent du repo)
2 docker image prune -f + note maintenance ports-registry
3 Pin images par digest (agent sha256:474477ad..., workspace sha256:2d2ba9aa...) hermes-platform 3f0db0a
4 Secrets Telegram (x3) + SESSION_SECRET (x3, perso ajoute) sortis du compose vers .env hermes-platform 3f0db0a
5 ports-registry : agents 8650/8660/8670 = internes uniquement (non publies) nas-runbooks 4933f77
6 Healthcheck sur les 3 workspaces (curl http://localhost:3000/) hermes-platform 3f0db0a
7 mem_limit 2G agents / 1G workspaces (deploy.resources.limits) hermes-platform 3f0db0a
8 scripts/cleanup-backups.sh (garde 2 derniers jeux de data.bak) hermes-platform 5949a70
9 Cle NVIDIA dediee Nyora (etait identique a TT) corrigee dans .env .env gitignore, pas de commit

Application des changements (a faire ensuite, avec accord)

cd /volume1/docker/hermes-platform
/usr/local/bin/docker compose up -d --force-recreate hermes-agent-tt    # puis nyora, perso
# verifier : stat -c %u:%g data = 1026:100 ; health = healthy ; UI 200

Pieges rencontres (hardening)

  • .env est root:root, non writable par Best0f, et pas de sudo : l editer via un conteneur jetable root : docker run --rm -v /volume1/docker/hermes-platform:/wd alpine sh -c sed -i ... /wd/.env.
  • git absent du NAS (host + containers) : tous les commits via API Gitea (basic auth bolbol).
  • Les compose par instance reutilisent les memes container_name -> collision (origine de b7f6e6ac8bbf_). Neutralises.
  • Le prune supprime l ancienne image agent 882e06b1ad23 : rollback image = re-pull, pas retag local.