Simple Bash scripts for backing up and restoring a local Hermes deployment using rsync over SSH.
The goal is disaster recovery: preserving the Hermes state and deployment configuration so a system can be rebuilt after hardware failure, OS reinstallation, or migration to a new machine.
- Incremental backups using
rsync - Timestamped snapshots
latestsymlink automatically updated after successful backups- Restore the latest snapshot or any previous snapshot
- Stores normal files and directories (no archive files)
- Uses SSH for transport
- Configuration kept separate from the scripts
- Safe for public repositories
The following programs must be available:
- Bash
- rsync
- ssh
- Docker
- Docker Compose
The backup destination must be reachable over SSH.
.
├── backup-hermes.sh
├── restore-hermes.sh
├── backup.conf.example
├── .gitignore
└── README.md
Your deployment directory will normally also contain:
.
├── .env
├── docker-compose.two-container.yml
├── backup-hermes.sh
├── restore-hermes.sh
├── backup.conf
└── README.md
Copy the example configuration:
cp backup.conf.example backup.conf
chmod 600 backup.confEdit backup.conf:
REMOTE_HOST="<backup-host>"
REMOTE_ROOT="<backup-root>"
# Optional
HERMES_HOME="${HOME}/.hermes"
# Optional
COMPOSE_FILENAME="docker-compose.two-container.yml"| Variable | Description |
|---|---|
REMOTE_HOST |
SSH hostname or SSH alias |
REMOTE_ROOT |
Remote directory where backups are stored |
HERMES_HOME |
Hermes persistent state directory |
COMPOSE_FILENAME |
Docker Compose file name |
The scripts automatically determine the deployment directory from their own location.
Make the scripts executable.
chmod 700 backup-hermes.sh
chmod 700 restore-hermes.shValidate the scripts:
bash -n backup-hermes.sh
bash -n restore-hermes.shIf ShellCheck is installed:
shellcheck backup-hermes.sh restore-hermes.shRun:
./backup-hermes.shThe script backs up:
.envdocker-compose.two-container.yml${HERMES_HOME}
A timestamped snapshot is created on the remote host.
Example:
<backup-root>/
├── latest
└── snapshots/
├── 2026-07-24_14-12-05/
├── 2026-07-25_18-31-40/
└── ...
Each snapshot contains:
deployment/
├── .env
└── docker-compose.two-container.yml
hermes-home/
backup-info.txt
BACKUP_COMPLETE
Restore the latest backup:
./restore-hermes.shRestore a specific snapshot:
./restore-hermes.sh 2026-07-24_14-12-05The script restores:
- Hermes state
.env- Docker Compose configuration
The restore requires confirmation before overwriting existing files.
After restoring:
docker compose \
-f docker-compose.two-container.yml \
up -dBefore making major system changes:
Stop the containers:
docker compose \
-f docker-compose.two-container.yml \
stopCreate a backup:
./backup-hermes.shRestart Hermes:
docker compose \
-f docker-compose.two-container.yml \
start- Install Docker.
- Install Docker Compose.
- Clone this repository.
- Create
backup.conf. - Run:
./restore-hermes.sh- Start Hermes:
docker compose \
-f docker-compose.two-container.yml \
up -dList snapshots:
ssh <backup-host> \
"find <backup-root>/snapshots -maxdepth 1 -type d | sort"Show the latest snapshot:
ssh <backup-host> \
"readlink -f <backup-root>/latest"Show snapshot sizes:
ssh <backup-host> \
"du -sh <backup-root>/snapshots/*"Preview a backup:
rsync -avzn \
"${HOME}/.hermes/" \
<backup-host>:<backup-root>/test/Preview deployment files:
rsync -avzn \
.env \
docker-compose.two-container.yml \
<backup-host>:<backup-root>/test/No files are transferred when using -n.
The following files should never be committed:
.envbackup.conf- SSH keys
- API keys
- Passwords
- Tokens
A recommended .gitignore:
.env
.env.*
!.env.example
backup.conf
*.pem
*.key
id_rsa
id_ed25519
snapshots/
latestBefore committing, review staged changes:
git diff --cached- The scripts use
rsync. -zcompresses data during transfer only.- Backups are stored as regular files and directories rather than archive files.
- Docker images and containers are not backed up.
- Docker recreates containers from the Compose file.
- The Hermes state is restored from the backed-up data.
Apache-2.0 License.