Sketch a Gitea backup strategy: alpha -> vlda-01

Now that alpha is the canonical live Gitea, vlda-01's stopped copy from
the migration just goes stale without something feeding it. Sketched
(not built) a design: gitea dump (not raw rsync, to avoid grabbing the
live SQLite DB mid-write) on a nightly cron on alpha, pulled by a
vlda-01-initiated cron job whenever it happens to be online - same
network-direction constraint as the rest of this plan, since alpha has
no route into the home LAN. Point-in-time backup, not a hot standby;
restore is a manual, deliberate step. Confirmed gitea dump is available
on this install and checked disk headroom on both ends before sizing
the retention window.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-26 16:02:29 +02:00
co-authored by Claude Sonnet 5
parent 8e0a2d3bf6
commit 94a367822f
+57
View File
@@ -55,6 +55,63 @@ outright, so alpha's availability stops depending on vlda-01's.
**Status: done, 2026-07-26 — see `README.md`'s "Gitea" section for the live **Status: done, 2026-07-26 — see `README.md`'s "Gitea" section for the live
setup.** vlda-01's copy left stopped as a cold backup, not decommissioned. setup.** vlda-01's copy left stopped as a cold backup, not decommissioned.
#### 2b. Ongoing backup: `git.jayfield.org` (alpha) → `vlda-01.home.jayfield.org`
**Status: sketch only, not built.** Now that alpha is the canonical live
Gitea, vlda-01's stopped copy will just get staler over time unless
something keeps feeding it. Goal here is a **backup**, not a hot standby
or live mirror — point-in-time recovery if alpha's Gitea is ever lost,
not instant failover.
**Same network constraint as everything else in this plan**: alpha has no
route into the home LAN (that's exactly the tunnel dependency removed
2026-07-19), and vlda-01 isn't guaranteed to be on. So the pull has to be
**initiated by vlda-01** whenever it happens to be up — never alpha
reaching in.
**Why not a raw `rsync` of `/srv/gitea/data`**: the DB is a live SQLite
file (`gitea.db`); rsyncing it while Gitea is writing risks grabbing it
mid-transaction and shipping a corrupt copy. Gitea ships a purpose-built
`gitea dump` command for exactly this (confirmed available on this
install/version) — it produces one consistent archive (DB + repos + LFS +
config together), which is also what Gitea's own restore procedure
expects, rather than reinventing consistency handling.
**Design**:
1. **On alpha** — a nightly cron job runs
`docker exec -u git gitea gitea dump -f /data/backups/gitea-dump-<date>.zip --skip-index`
(`--skip-index` drops the regenerable Bleve search index, which isn't
needed to restore and just adds size/time) into
`/srv/gitea/data/backups/` (a subdirectory of the same bind mount, so
it's already host-inspectable without extra volumes). Prune to the
last ~14 daily archives in the same job — at the repo sizes seen here
(~4GB total) that's a bounded, comfortable footprint against alpha's
136GB free.
2. **On vlda-01** — a cron job (running whenever vlda-01 is powered on;
picks up wherever it left off, same "catches up automatically"
philosophy as the Syncthing files plan above) pulls the newest archive
from alpha via `rsync`/`scp` over SSH into a dedicated backup directory
(plenty of headroom on the Unraid array — 3.7TB free at last check).
Keep its own retention window there too, independent of alpha's.
3. **Restore path, if ever needed**: manual, deliberate — stop the target
Gitea container, unpack the chosen dump's DB/repos/etc. into `/data`
per Gitea's documented restore steps, restart, verify. Not automated;
matches how every other risky operation in this repo is handled
(careful, verified, not blind).
4. **Explicitly out of scope for this design**: real-time replication,
automatic failover, or DNS/traffic cutover — none of that fits a
personal git host's actual usage pattern (a handful of commits per
session), and the added complexity/failure surface wouldn't be worth
it. Revisit if that ever changes.
5. **Future consolidation**: if/when Syncthing (item 1 above) actually
gets built, it could carry these dump archives too instead of a
separate rsync/cron pull — one sync mechanism instead of two. Not
worth blocking this on Syncthing existing first, though.
**Open question before building**: nightly cadence assumed above — confirm
that matches how often this actually needs protecting (probably fine,
given commit frequency, but worth a sanity check before automating it).
### 3. Jellyfin → scoping question, not yet planned ### 3. Jellyfin → scoping question, not yet planned
Media libraries are often hundreds of GB to multiple TB, and local hardware Media libraries are often hundreds of GB to multiple TB, and local hardware