docs: update README and RUNBOOK for multi-deployment config

- 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
This commit is contained in:
2026-08-30 23:50:38 +01:00
co-authored by Claude Sonnet 4.6
parent 74390b78af
commit f3cf24a41c
2 changed files with 205 additions and 138 deletions
+28 -13
View File
@@ -1,23 +1,38 @@
# backup-agent
Backup and disaster-recovery tooling for a Linux server: [Borg](https://borgbackup.readthedocs.io/)
backing up `/home/srv/files/content` — including a MariaDB database
running in Docker — with an offsite mirror on Scaleway S3 via `rclone`.
Backup and disaster-recovery tooling for Linux servers: [Borg](https://borgbackup.readthedocs.io/)
backing up a target directory tree — including a MariaDB database running in
Docker — with an offsite mirror on Scaleway S3 via `rclone`.
MariaDB is never stopped during backup: `dump_db.sh` takes a
transactionally-consistent logical dump (`mysqldump --single-transaction`)
while the container keeps running, and the container's raw data directory
is excluded from the archive entirely (a `.nobackup` marker file), so only
the logical dump ever gets backed up. Zero DB downtime.
while the container keeps running, and the container's raw data directory is
excluded from the archive entirely (a `.nobackup` marker file), so only the
logical dump ever gets backed up. Zero DB downtime.
## Components
| File | Purpose |
|---|---|
| `configs/` | Per-deployment config files (one per server). Each sets `TARGET`, `REPO`, `DB_CONTAINER`, etc. |
| `borg-backup.sh` | Daily backup orchestrator (run from cron): dump → archive → prune → compact → integrity check → offsite sync. |
| `dump_db.sh` | Per-database `mysqldump`/`mariadb-dump`, atomic staging/swap. Invoked by `borg-backup.sh`. |
| `restore.sh` | Recovery CLI: `full` (disaster recovery), `db <name>` (single database), `file <path>` (single file/dir), `--list-archives`. Every mode supports `--dry-run`. |
## Multi-server use
Both scripts are deployment-agnostic. Point them at a config with `BACKUP_CONF`:
```bash
# backup
BACKUP_CONF=/opt/backup-agent/configs/nexusvoice.conf /opt/backup-agent/borg-backup.sh
# restore
BACKUP_CONF=/opt/backup-agent/configs/nexusvoice.conf /opt/backup-agent/restore.sh --list-archives
```
See `configs/` for existing deployments and `RUNBOOK.md §2` for deployment steps.
## Quickstart
```bash
@@ -37,16 +52,16 @@ Day to day:
## Encryption
The Borg repo at `/home/srv/files/backups/borg-2025` is **unencrypted** by
deliberate choice on this deployment`borg-backup.sh` will keep printing
a warning about it on every run, which is expected. See `RUNBOOK.md` if
you want to switch to an encrypted repo.
The Borg repos on current deployments are **unencrypted** by deliberate operator
choice`borg-backup.sh` will keep printing a warning about it on every run,
which is expected. See `RUNBOOK.md` if you want to switch to an encrypted repo.
## Requirements
`borg`, `docker`, `rclone`, `flock`, a `mysql`/`mariadb` client — see
`REQUIRED_CMDS` in `borg-backup.sh`. Targets Linux; `flock(1)` doesn't
exist on macOS, so these scripts won't run as-is on a Mac.
`borg`, `docker`, `rclone`, `flock`, a `mysql`/`mariadb` client. When
`DB_CONTAINER` is empty in the config, `docker` is not required. Targets
Linux; `flock(1)` doesn't exist on macOS, so these scripts won't run as-is
on a Mac.
## License