2.7 KiB
2.7 KiB
Encrypted Hermes Backup Pipeline
Issue: timmy-home#693
This pipeline creates a nightly encrypted archive of ~/.hermes, stores a local encrypted copy, uploads it to remote storage, and supports restore verification.
What gets backed up
By default the pipeline archives:
~/.hermes/config.yaml~/.hermes/state.db~/.hermes/sessions/~/.hermes/cron/- any other files under
~/.hermes
Override the source with BACKUP_SOURCE_DIR=/path/to/.hermes.
Backup command
BACKUP_PASSPHRASE_FILE=~/.config/timmy/backup.passphrase \
BACKUP_NAS_TARGET=/Volumes/timmy-nas/hermes-backups \
bash scripts/backup_pipeline.sh
The script writes:
- local encrypted copy:
~/.timmy-backups/hermes/<timestamp>/hermes-backup-<timestamp>.tar.gz.enc - local manifest:
~/.timmy-backups/hermes/<timestamp>/hermes-backup-<timestamp>.json - log file:
~/.timmy-backups/hermes/logs/backup_pipeline.log
Nightly schedule
Run every night at 03:00:
0 3 * * * cd /Users/apayne/.timmy/timmy-home && BACKUP_PASSPHRASE_FILE=/Users/apayne/.config/timmy/backup.passphrase BACKUP_NAS_TARGET=/Volumes/timmy-nas/hermes-backups bash scripts/backup_pipeline.sh >> /Users/apayne/.timmy-backups/hermes/logs/cron.log 2>&1
Remote targets
At least one remote target must be configured.
Local NAS
Use a mounted path:
BACKUP_NAS_TARGET=/Volumes/timmy-nas/hermes-backups
The pipeline copies the encrypted archive and manifest into <BACKUP_NAS_TARGET>/<timestamp>/.
S3-compatible storage
BACKUP_PASSPHRASE_FILE=~/.config/timmy/backup.passphrase \
BACKUP_S3_URI=s3://timmy-backups/hermes \
AWS_ENDPOINT_URL=https://minio.example.com \
bash scripts/backup_pipeline.sh
Notes:
awsCLI must be installed ifBACKUP_S3_URIis set.AWS_ENDPOINT_URLis optional and is used for MinIO, R2, and other S3-compatible endpoints.
Restore playbook
Restore an encrypted archive into a clean target root:
BACKUP_PASSPHRASE_FILE=~/.config/timmy/backup.passphrase \
bash scripts/restore_backup.sh \
/Volumes/timmy-nas/hermes-backups/20260415-030000/hermes-backup-20260415-030000.tar.gz.enc \
/tmp/hermes-restore
Result:
- restored tree lands at
/tmp/hermes-restore/.hermes - if a sibling manifest exists, the restore script verifies the archive SHA256 before decrypting
End-to-end verification
Run the regression suite:
python3 -m unittest discover -s tests -p 'test_backup_pipeline.py' -v
This proves:
- the backup output is encrypted
- plaintext archives do not leak into the backup destinations
- the restore script recreates the original
.hermestree end-to-end - the pipeline refuses to run without a remote target