主题
Hermes Version Bump Runbook
Pinned source of truth: scripts/admin/spawn-profile.sh:160 (HERMES_IMAGE).
Upstream image: https://hub.docker.com/r/nousresearch/hermes-agent/tags
Current pinned tag: 0.13.0 (matches ECS production as of 2026-05-16, per instance-lifecycle-rebuild.md).
When to bump
- Upstream ships a fix you actively need (regression in current tag, security advisory).
- Upstream ships a feature ProvisionWorker / config template depends on (e.g., new env var, new gateway endpoint).
- Quarterly cadence check: walk through changelog, decide stay vs. move.
Do not bump on cron just to "stay current." Each bump is a small ops event; treat it like deploying any other dependency upgrade.
Procedure
1. Verify the target tag
bash
# Confirm the tag exists and pull its digest
docker pull nousresearch/hermes-agent:<NEW_TAG>
docker inspect --format '{{.Id}}' nousresearch/hermes-agent:<NEW_TAG>Skim upstream changelog/release notes for:
- CLI /
gateway runargument changes - Env var renames or new required vars (compare against
profile/template-stock-research-pro/config.yaml.template+spawn-profile.sh:122-153env block) - Dashboard port / auth changes (
9119today) - Healthcheck endpoint shape (
/api/statustoday)
If any of the above changed, the bump is not just a tag swap — needs a real PR with paired code edits.
2. PR
Single-line change in scripts/admin/spawn-profile.sh:160:
bash
HERMES_IMAGE="${HERMES_IMAGE:-nousresearch/hermes-agent:<NEW_TAG>}"PR title: chore(hermes): pin hermes-agent <OLD> → <NEW>
PR body must include:
- Link to upstream release notes
- Diff of any required CLI / env / config changes
- Rollback plan: previous tag string
Merge to main. Auto-deploy pipeline (deploy-ecs.yml) does not restart Hermes containers — only the FastAPI data backend + NestJS app backend + frontend.
3. ECS-side pull
SSH to ECS (ssh-ecs.fsagent.cc):
bash
docker pull nousresearch/hermes-agent:<NEW_TAG>Pull only — do not restart existing containers yet.
4. Rolling rebuild (manual, one container at a time)
For each active hermes-<profile> container:
bash
# Find profile name
docker ps --filter "name=hermes-" --format '{{.Names}}\t{{.Image}}'
# Stop + destroy (clears volumes mounted ro, NOT profile dir)
docker stop hermes-<profile>
docker rm hermes-<profile>
# Re-spawn with new image (HERMES_IMAGE from updated spawn-profile.sh)
cd /home/twilight/twilight-app/source
git pull origin main # picks up the new HERMES_IMAGE value
sudo -u twilight ./scripts/admin/spawn-profile.sh --profile <profile> --tier <tier> ...Verify each container after rebuild:
bash
docker exec hermes-<profile> curl -sf http://127.0.0.1:9119/api/status
docker logs --tail 50 hermes-<profile>If any container fails to come back up:
- Inspect logs:
docker logs hermes-<profile> - Most likely cause: new image broke a CLI arg or env var
- Roll back that profile only: re-spawn with
HERMES_IMAGE=nousresearch/hermes-agent:<OLD_TAG>override - Then revert PR
5. Monitor
For 24h post-bump:
- Watch ECS logs:
journalctl -u docker -f - Check
/services/instance/:sub/provision-statusfor failure spikes - Spot-check a user via WeChat → Hermes reply
If failure rate climbs, revert PR + run procedure with old tag.
Rollback
- Revert PR on
main(setsHERMES_IMAGEback to old tag) - SSH ECS →
git pull(gets old tag back into spawn-profile.sh) - For each affected container:
docker rm -f+ re-spawn (spawn-profile.sh now reads old tag) docker pull nousresearch/hermes-agent:<OLD_TAG>(in case old tag was image-pruned)
What this runbook does NOT cover
- Hermes profile template changes (
profile/template-stock-research-pro/**). Those need their own PR + per-user~/.hermes/profiles/<name>/reconciliation. - GHCR mirror of Hermes image (future work, see
2026-05-16-hermes-image-pin.md). - Auto-bump GitHub Action listening on upstream releases (future work).