3-2-1 backup tiering with off-site cold (Jottacloud candidate)

- s3.nuclide.systems is on-site only — recasting it as the WARM tier,
  not the disaster-recovery copy. Off-site cold becomes a separate
  decision tracked as Q20.
- docs/12 #37 expanded with full provider comparison: Jottacloud
  Unlimited (~€9.50/mo, EU/Norway, soft-cap ~5 TB) is the user's
  stated candidate and a reasonable fit for the current 2 TB scale
  with ~10 years of headroom. Alternatives priced: Hetzner Storage
  Box, Backblaze B2, rsync.net, Storj. Always restic/rclone-crypt
  before upload.
- Off-site priority list pinned: Immich originals + documents +
  Nextcloud user data + Vaultwarden DB go off-site; movies / music /
  ROMs / derived caches don't.
- docs/10 backup section rewritten as the 3-2-1 pipeline (source →
  UNAS native snapshot → warm → encrypted cold). Nexa-specific
  snapshot rows updated for the new collection names.
- docs/11 Q20 added with the decision criteria.
- CLAUDE.md: backup model pinned so future agents don't propose
  alternative paths.
This commit is contained in:
Claude
2026-05-05 04:50:43 +00:00
parent e8f0d9a2c2
commit dfd9aa7d2a
4 changed files with 49 additions and 10 deletions
+36 -6
View File
@@ -106,13 +106,43 @@ These three are inter-related — picking them up as one campaign is cheaper tha
Output: a one-page table `service | persistent? | currently bound to | should be bound to`. Then migrate the non-compliant ones one-by-one (stop → rsync data to `services/<svc>/` on UNAS → re-create stack with the new bind → verify → keep the old volume for 7 days as a rollback). Lock the convention for any new stack going forward.
37. **S3 archive tier (`s3.nuclide.systems`).** Currently UNAS holds backups in `backup/<svc>/` and there's no cold offsite. Make `s3.nuclide.systems` the canonical *cold* tier:
- **Restic / borg** repos targeting S3 for: `backup/home-assistant/`, `backup/immich/`, `backup/nextcloud/`, future `backup/nexa/`. Backrest already orchestrates Borg — just add an S3 destination.
- **Qdrant + GraphDB snapshots** flow UNAS → S3 weekly (daily on UNAS, weekly to S3 = cheap, keeps the most recent locally for fast restore).
- **Immich photo originals** to S3 if the photo library grows past UNAS comfort. Immich has native S3 support via its `IMMICH_*` env vars.
- Resolves [Q12](./11-open-questions.md#q12) — once the bucket name + access key are set, every other archive just adds a target.
37. **3-2-1 backup tiering: warm on-site (S3) + cold off-site.**
`s3.nuclide.systems` is already up but it's **on-site** — same building, same power, same (in-)susceptibility to fire / theft / ransomware. By itself it's a *warm* tier, not a disaster-recovery copy. The full design is two tiers:
This is the right time to do it because we're about to add Nexa snapshots; designing the path for *all* services rather than just Nexa avoids one-offs.
**Warm tier — `s3.nuclide.systems` (already exists, just needs a bucket):**
- **Restic / borg** repos for `backup/home-assistant/`, `backup/immich/`, `backup/nextcloud/`, future `backup/nexa/`. Backrest already orchestrates Borg — just add the S3 destination.
- **Qdrant + GraphDB snapshots** flow UNAS → S3 daily.
- Resolves [Q12](./11-open-questions.md#q12) once the bucket name + access key are set.
**Cold tier — off-site provider (decision pending — see [Q20](./11-open-questions.md#q20)):**
- **Jottacloud "Unlimited"** (~€9.50/mo, EU/Norway, soft-cap ~5 TB) — user's stated candidate. Best price/value at current 2 TB; reach soft cap in ~10 years. Use `rclone jottacloud:` or native `jotta-cli`.
- **Hetzner Storage Box BX21** (€13/mo, 5 TB EU/DE) — predictable quota, native Borg/Restic/SFTP. Cheapest predictable EU alternative.
- **Backblaze B2** (~$12/mo for 2 TB, S3-compatible, US) — cheapest with the widest tooling support; egress is paid (~$10/TB) which only bites during *full* restores.
- **rsync.net** (~$30/mo) — ZFS send/recv natively; overkill unless you want pool replication.
- **Storj DCS** ($4/TB/mo, decentralized, S3-compatible) — newer ecosystem.
**Always encrypt before upload** regardless of provider — `restic` or `rclone crypt` over the chosen remote. The provider sees only ciphertext blobs. Key material lives in Vaultwarden + a printed-paper offline copy.
**Tiering & cadence:**
```
[Source] UNAS RAID-6 + native snapshots (#38)
│ daily restic/borg
[Warm] s3.nuclide.systems (on-site, fast restore)
│ weekly rclone copy + crypt
[Cold] Off-site (Jottacloud / B2 / Hetzner) ← satisfies the "1" in 3-2-1
```
**What goes off-site (priority order):**
1. Immich photo originals — irreplaceable.
2. `media/documents/`, `_sortMe/Downloads/`, Nextcloud user data — irreplaceable.
3. Memos DB, n8n workflows, Nexa Qdrant + GraphDB snapshots — replicable from sources but expensive to redo.
4. Vaultwarden DB — *cryptographically* sensitive but small; explicitly include.
**What does not need off-site:** movies, music, audiobooks, ROMs, derived caches (Immich thumbnails, encoded-video). Those re-download or regenerate.
Pre-deploy step: choose one provider, create a test bucket/folder, dry-run a `restic init` + `restic backup` of `backup/nexa/` first as a smoke test before pointing the heavyweight repos at it.
38. **Configure UNAS Pool snapshots.** The UniFi Drive dashboard shows the storage-pool snapshot schedule as "Click to Setup" — i.e. **not configured**. RAID 6 protects against drive failure, not against an `rm -rf` from a misbehaving container or a Nextcloud user mass-delete. Cheap fix: set a daily snapshot with 7-day retention + a weekly with 4-week retention on Pool 1. Native to UniFi Drive, no agent needed. **Highest-leverage data-protection change in the homelab right now** — costs nothing, recovers everything.