- README: remove hardcoded srv paths; add configs/ to components table;
document BACKUP_CONF usage for multi-server setups; note DB_CONTAINER=
makes docker optional
- RUNBOOK: generalize §1 setup to use config variables (source config,
use $REPO / $BORG_PASSPHRASE_FILE / etc. instead of hardcoded paths);
§4 day-2 ops now shows source-config pattern before direct borg commands;
§5 recovery notes BACKUP_CONF for restore.sh; §6 drill uses config vars
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A3rQSEidP6Y61kaCtxjVV1
Both borg-backup.sh and restore.sh now source a config file instead of
hardcoding paths and container names. Default is backup.conf next to the
script; override with BACKUP_CONF=/path/to/other.conf.
- configs/srv.conf — current server (unchanged behaviour)
- configs/nexusvoice.conf — nexusvoice server (/home/acid/nexusvoice,
separate Scaleway path par-backup-1/nexusvoice)
- DB steps in borg-backup.sh are now guarded on [[ -n "$DB_CONTAINER" ]]
so a config with DB_CONTAINER="" skips the dump entirely
- RUNBOOK.md §2 documents single and multi-deployment patterns
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A3rQSEidP6Y61kaCtxjVV1
dump_db.sh no longer lives under $TARGET, so its own default dump
directory (relative to wherever the script is) would land outside the
backed-up tree. Pin DUMP_SCRIPT to /opt/backup-agent/dump_db.sh and
export DUMP_DIR explicitly so dumps still land in $TARGET/mariadb/dump
regardless of where the script itself is deployed.
Also drop the healthcheck integration (HEALTHCHECK_URL, send_healthcheck,
curl requirement) from borg-backup.sh per request - no monitoring hook
wanted for now.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Final review of the restore.sh branch found cmd_full restored every
database via `docker exec` before starting the container, which fails
immediately in the exact scenario full restore exists for (a freshly
rebuilt, stopped container). Reorders to extract -> start container ->
restore DBs.
Also, while touching cmd_full:
- Extract directly into place (cd / && borg extract) instead of staging
a full copy under /tmp then cp -a'ing it into $TARGET - halves disk
usage and restore time.
- Replace `rm -rf "$TARGET"/*` with `find "$TARGET" -mindepth 1 -delete`
so dotfiles don't survive a --force wipe.
- Add acquire_lock() (shares borg-backup.sh's lockfile so a restore and
the nightly backup cron can't run concurrently) and preflight()
(passphrase file readable, repo reachable) before any real work in
full/db/file.
Test isolation: mock borg/docker/mysql/mariadb consistently via a
BASH_ENV shim (previously only db-mode's test worked around PATH
shadowing by a real docker binary; every mocked test needed it, and a
missing `flock` mock broke everything once acquire_lock was added,
since flock(1) doesn't exist on macOS). Tests also isolate LOCKFILE and
BORG_PASSPHRASE_FILE to throwaway paths.
RUNBOOK.md: fix the quarterly drill command (borg extract has no
--destination flag, and needs `borg list --short` for a bare archive
name), reword the full-restore --force comment which read backwards,
and document the MYSQL_ROOT_PASSWORD/RESTORE_LOGDIR env overrides and
where restore logs land.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>