blumeops/docs/reference/storage/backups.md
Erich Blume c78b86c72c Add offsite backup for immich photo library to BorgBase (#315)
## Summary

- Adds a second borgmatic config (`photos.yaml`) that backs up `/Volumes/photos` (sifaka SMB mount, ~128 GB) to a dedicated BorgBase repo (`immich-photos`), running daily at 4 AM
- Separate launchd agent (`mcquack.eblume.borgmatic-photos`) so photo backups run independently from the main backup
- Refactors `borgmatic_metrics` script to support multiple repos with a `repo` Prometheus label
- Updates Grafana "Borg Backups" dashboard with a `repo` template variable so you can filter/compare repos
- Docs updated: `backups.md`, `borgmatic.md`

## Prerequisites (manual)

- [x] Create `immich-photos` repo on BorgBase with same SSH key
- [ ] Upgrade BorgBase plan to Small ($24/yr) if currently on free tier (128 GB exceeds 10 GB limit)
- [ ] After deploy: `borg init` the new repo (borgmatic does this automatically on first run)

## Test plan

- [ ] Dry run: `mise run provision-indri -- --check --diff --tags borgmatic,borgmatic_metrics`
- [ ] Deploy borgmatic role and verify both configs deployed
- [ ] Run `borgmatic --config ~/.config/borgmatic/photos.yaml create --verbosity 1` manually for first backup (will take hours)
- [ ] Verify metrics script collects from both repos: `~/.local/bin/borgmatic-metrics && cat /opt/homebrew/var/node_exporter/textfile/borgmatic.prom`
- [ ] Sync grafana-config in ArgoCD and verify dashboard repo selector works

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Reviewed-on: #315
2026-03-27 19:43:05 -07:00

3.1 KiB

title modified tags
Backups 2026-03-27
storage
backup

Backup Policy

Daily automated backups from indri to sifaka NAS.

Schedule

Time Frequency System
2:00 AM Daily borgmatic

What Gets Backed Up

Directories

Path Description Priority
~/code/personal/zk Zettelkasten notes Critical
/opt/homebrew/var/forgejo Git repositories Critical
~/.config/borgmatic Backup config High
~/Documents Personal documents (includes 1password encrypted export) High

Databases

Database Cluster Host Method
miniflux blumeops-pg [[postgresql pg.ops.eblu.me:5432]]
teslamate blumeops-pg [[postgresql pg.ops.eblu.me:5432]]
authentik blumeops-pg [[postgresql pg.ops.eblu.me:5432]]
immich immich-pg [[postgresql pg.ops.eblu.me:5433]]
mealie — (SQLite) k8s pod kubectl exec sqlite3 .backup

Immich Photo Library (Offsite Only)

The immich photo library lives on sifaka at /volume1/photos (SMB-mounted on indri as /Volumes/photos). Since sifaka is already the local backup target, photos are backed up to BorgBase offsite only — not back to sifaka.

Property Value
Config ~/.config/borgmatic/photos.yaml
Schedule Daily at 4:00 AM (offset from main backup)
Source /Volumes/photos (sifaka SMB mount)
Target BorgBase borgbase-immich-photos repo
Size ~128 GB

Uses the same encryption passphrase and SSH key as the main borgmatic config.

Sifaka-Native Data

Other data lives directly on sifaka (music via navidrome, video via jellyfin). See sifaka for data protection details.

What Is NOT Backed Up

Data Reason
ZIM archives (~/transmission/) Re-downloadable via torrent
Prometheus metrics Ephemeral, in k8s PVC
Loki logs Ephemeral, in k8s PVC
devpi cache Re-fetchable from PyPI

Retention Policy

Period Retention
Daily 7 backups
Monthly 12 backups
Yearly 1000 backups

Backup Targets

Repository Location Label Backs up
/Volumes/backups/borg/ sifaka (local NAS) sifaka-borg-backups indri data
ssh://u3ugi1x1@...repo.borgbase.com/./repo BorgBase (offsite) borgbase-offsite indri data
ssh://xcrtl5tg@...repo.borgbase.com/./repo BorgBase (offsite) borgbase-immich-photos immich photos

Monitoring

Metrics exposed to prometheus:

  • borgmatic_up - Repository accessible
  • borgmatic_last_archive_timestamp - Last backup time
  • borgmatic_repo_deduplicated_size_bytes - Disk usage

Dashboard: "Borgmatic Backups" in grafana