Establish the design foundation for the heleosv2 multi-tenant hosting platform before any implementation code: - Monorepo skeleton: docs/, platform-infra/, site-templates/, deployments/, control-panel/ with orientation READMEs. - docs/: roadmap index, architecture + threat model, naming conventions, site profiles, provisioning workflow, backup & DR runbook, repo/GitOps layout, and the approved architecture plan. - docs/adr/: 9 ADRs recording the rationale for single-host Compose, Traefik edge, nginx+fpm split, shared MariaDB, ZFS-per-customer, decoupled backup streams, Forgejo, CLI-first, and SFTP-only. - Secrets hygiene: .gitignore (only *.enc.* committed) and .gitattributes (LF for scripts/Dockerfiles/YAML run on the Linux host). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
35 lines
1.7 KiB
Markdown
35 lines
1.7 KiB
Markdown
# ADR 0006 — Decoupled backup streams (files vs DB vs logs)
|
|
|
|
**Status:** Accepted
|
|
|
|
## Context
|
|
An earlier proposal wrote per-database dumps *into* each customer's ZFS dataset
|
|
just before snapshotting, so one snapshot contained files + DB. Problem: the dump
|
|
changes every night even for a static site, so every incremental `zfs send`
|
|
would ship a fresh dump — defeating the cheap-incremental goal of
|
|
[ADR 0005](0005-zfs-per-customer.md). Logs in the dataset cause the same bloat.
|
|
|
|
## Decision
|
|
Back up each data type with the mechanism that fits its change pattern, in
|
|
**three decoupled streams**:
|
|
|
|
1. **Web files** → ZFS snapshot + `zfs send` offsite (truly incremental;
|
|
near-zero when unchanged).
|
|
2. **Databases** → **automysqlbackup** produces per-database dumps with
|
|
daily/weekly/monthly rotation into `tank/platform/db-backups/<customer>`, then
|
|
**rsync** offsite. Per-database dumps preserve per-customer restore
|
|
granularity.
|
|
3. **Logs** → shipped to **Loki** via Promtail; never stored in the customer
|
|
dataset.
|
|
|
|
## Consequences
|
|
- ✅ Unchanged sites cost almost nothing to back up offsite.
|
|
- ✅ Each stream is independently tunable (retention, cadence, target).
|
|
- ❌ Restoring a customer is a **two-step** operation (files from ZFS, DB from
|
|
the dump repo) rather than a single snapshot rollback — documented in the
|
|
[DR runbook](../06-backup-and-dr.md).
|
|
- ⚠️ The streams are **crash-consistent, not atomically consistent**. Schedule
|
|
the nightly DB dump close to the ZFS snapshot; the small window is harmless for
|
|
PHP/WordPress (files-on-disk + DB-rows).
|
|
- ↔️ Optional future: place `db-backups` on its own dataset and `zfs send` it for
|
|
checksummed/immutable offsite instead of rsync.
|