Files
backup-agent/README.md
T
kevin.batailleandClaude Sonnet 4.6 f3cf24a41c 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
2026-08-30 23:50:38 +01:00

69 lines
2.5 KiB
Markdown

# backup-agent
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.
## 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
# One-time setup, deployment, cron scheduling, day-2 ops, and step-by-step
# recovery for every scenario are all in:
less RUNBOOK.md
```
Day to day:
```bash
./restore.sh --list-archives # what backups exist
./restore.sh full --dry-run # preview a disaster recovery
./restore.sh db <name> --dry-run # preview a single-database restore
./restore.sh file <path> --dest DIR # pull one file out of an archive
```
## Encryption
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. 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
None specified — internal tooling.