Worked guide

Back up Hermes and rehearse a restore

Make an encrypted copy of a stopped native install’s state, restore it somewhere empty, and compare it before updating.

You’ll finish with
An encrypted archive and a verified separate restore directory.
Before you start
macOS, Linux or WSL, GnuPG, enough backup space, and the paths used by your actual running services. Docker installs need their volume paths instead.

1. Identify the state and record the versions

For a default native install, the Agent home is ~/.hermes and WebUI state is its webui directory. A service can use a different HERMES_HOME; HERMES_WEBUI_STATE_DIR can place WebUI state outside it. Use the running service’s paths, not an unrelated terminal’s defaults.

HERMES_SNAPSHOT_HOME="${HERMES_HOME:-$HOME/.hermes}"
HERMES_BACKUP_DIR="$HOME/hermes-backups"
umask 077
mkdir -p "$HERMES_BACKUP_DIR"
du -sh "$HERMES_SNAPSHOT_HOME"
HERMES_WEBUI_DIR="/path/to/your/hermes-webui"
git -C "$HERMES_WEBUI_DIR" rev-parse HEAD > "$HERMES_BACKUP_DIR/webui-revision.txt"

Replace /path/to/your/hermes-webui with your actual native checkout. For Docker, record the running image tag or digest instead of this Git command. Also record the Agent release or revision and your launcher. Include every active profile, external workspace, browser profile and memory store needed for recovery. If WebUI state is outside the Agent home, make a second encrypted archive of that directory. A Git revision alone does not back up sessions or secrets.

2. Stop writers and create the encrypted archive

Pause scheduled jobs and stop every process writing these directories. For a foreground launch use Ctrl+C; a WebUI daemon started with ctl.sh uses ./ctl.sh stop. Stop the relevant Agent gateway or service too, using the manager that started it. Include named-profile gateways; do not assume stopping one browser tab stops the backend.

Run the following in a private Bash terminal. GnuPG asks for the archive passphrase; keep it outside the agent’s routine access. Keep the backup directory outside the source being archived.

set -o pipefail
HERMES_ARCHIVE="$HERMES_BACKUP_DIR/hermes-home-$(date +%Y%m%d-%H%M%S).tar.gz.gpg"
tar -C "$HERMES_SNAPSHOT_HOME" -czf - . | \
  gpg --symmetric --cipher-algo AES256 --output "$HERMES_ARCHIVE"
test -s "$HERMES_ARCHIVE" && printf 'Archive written: %s\n' "$HERMES_ARCHIVE"

Expected: both pipeline commands succeed and the encrypted file is non-empty. If tar reports unreadable or changing files, or the pipeline returns an error, fix the cause and make a new archive. A full home can contain large caches and sandboxes; the size check helps you plan storage.

3. Restore into an empty test directory

Do not extract over your live home. In the same private terminal:

HERMES_RESTORE_DIR="$(mktemp -d)"
gpg --decrypt "$HERMES_ARCHIVE" | tar -xz -C "$HERMES_RESTORE_DIR"
cmp "$HERMES_SNAPSHOT_HOME/config.yaml" "$HERMES_RESTORE_DIR/config.yaml"
printf 'Restore directory: %s\n' "$HERMES_RESTORE_DIR"

Expected: decryption and extraction succeed; cmp prints nothing and exits 0. Use another known file if this install has no config.yaml. Compare a representative memory or session file too, without printing its contents. Keep the restore directory private: it contains decrypted state.

Do not start the restored Agent yet. It may contain live schedules and integrations. A vault using an OS-keychain key also needs that keychain entry; the encrypted vault file alone is not a recovery plan. See the vault backup boundary.

4. Update only after the restore works

Read the release’s compatibility notes and record the target Agent and WebUI versions. The website installer follows the repository’s default branch; it does not pin a stable release. Docker’s stable and experimental channels are separate.

Keep the archive and matching revisions together. If an upgrade migrates state, switching the code back does not necessarily reverse the migration. For a rollback, stop writers again and restore the pre-upgrade snapshot with its matching versions. Keep outbound jobs disabled until you have checked the restored sessions, settings and a test conversation.

For Docker installs

Identify the volumes and bind mounts in your actual Compose deployment. Stop its writers, then back up those volumes with a volume-aware process; the host’s ~/.hermes may not be the container’s state. Follow the maintained Docker guide, including the source-volume upgrade step for a two-container install. Do not assume pulling a new image updates a separate mounted Agent checkout.

After a successful rehearsal, store another encrypted backup off the machine and record where its recovery passphrase is held. Remove the decrypted test restore when your check is complete; keep the encrypted archive.

Sources and next steps

All practical guides