Skip to content

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 run argument changes
  • Env var renames or new required vars (compare against profile/template-stock-research-pro/config.yaml.template + spawn-profile.sh:122-153 env block)
  • Dashboard port / auth changes (9119 today)
  • Healthcheck endpoint shape (/api/status today)

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-status for failure spikes
  • Spot-check a user via WeChat → Hermes reply

If failure rate climbs, revert PR + run procedure with old tag.


Rollback

  1. Revert PR on main (sets HERMES_IMAGE back to old tag)
  2. SSH ECS → git pull (gets old tag back into spawn-profile.sh)
  3. For each affected container: docker rm -f + re-spawn (spawn-profile.sh now reads old tag)
  4. 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).

团队内部文档