PR 1: backup role with borgmatic + NFS-to-UniFi rsync
Created by: jedmund
Summary
First PR in a 4-PR series adding scheduled backups to the homelab. This one establishes the plumbing: borgmatic running in a container on nuc-mini, snapshotting /opt/docker to a local Borg repo, rsync'ing the repo to an NFS-mounted UniFi Drive share where the existing UniFi to Backblaze sync ships it offsite.
nuc-mini
├── borgmatic container ──[local repo]──▶ /var/backup/borg
└── after_actions: rsync ──▶ /mnt/nas/backup (NFS mount of UniFi share)
│
▼
existing UniFi Drive to Backblaze
In scope
- Borgmatic container, internal cron at 02:00 daily
-
keep_daily: 30retention -
repokey-blake2encryption, passphrase via vault - NFS mount of UniFi share via systemd
automount(non-blocking on boot) - Post-backup rsync runs inside the container via
after_actions -
/opt/dockersource path,/opt/docker/musicbrainzexcluded (reproducible from upstream) - Custom Dockerfile extending
ghcr.io/borgmatic-collective/borgmaticwithrsyncandnfs-common
Not in scope here (subsequent PRs)
- Database consistency: PR 2 adds Borgmatic's native PostgreSQL and MongoDB hooks plus custom
before_backupscripts for CouchDB and SQLite. Don't trust DB restores from snapshots taken before PR 2 ships. - Web UI: PR 3 adds borg-ui with native PocketID OIDC at
backup.atelier.house. - Monitoring: PR 4 adds Healthchecks.io dead-man's-switch plus Netdata scrape of borgmatic's Prometheus exporter.
Commits
-
backup: add role for borgmatic local-repo snapshots: role itself plus deploy playbook -
infra: wire backup into orchestration: inventory group plus all.yml import Makefile: add deploy-backup target-
backup: lock in real UniFi NAS values: NAS at 192.168.1.3, Homelab share
Pre-deploy checklist
Before running make deploy-backup for the first time:
- Create the vault file
group_vars/backup/vault.yml:Thenborg_passphrase: <strong random string, 32+ chars>ansible-vault encrypt group_vars/backup/vault.yml. Save the passphrase outside the repo too, because losing it means losing the repo permanently.
The NAS share, IP, and NFS export path are already locked in via commit 4.
Bootstrap (one-time, after first deploy)
ssh nuc-mini
# Initialize the empty repo
docker exec -it borgmatic borgmatic rcreate --encryption repokey-blake2
# Trigger the first backup manually (will take hours)
docker exec borgmatic borgmatic --verbosity 1
Subsequent runs happen on the internal 02:00 cron.
Test plan
-
make deploy-backupcompletes with no errors -
/mnt/nas/backupis mounted (mount | grep nas) and writable -
docker logs borgmaticshows the cron picking up the schedule -
After bootstrap init plus first manual run, docker exec borgmatic borg list /reposhows at least one archive -
ls /mnt/nas/backup/borg-nuc-mini/shows segment files matching/var/backup/borg/ -
Force a config redeploy and confirm the handler restarts the stack with recreate: always -
Reboot nuc-miniand confirm theautomountdoesn't block boot if NAS is unreachable