ADR-003: Self-hosted home cluster behind Cloudflare Tunnel
Status: Accepted Date: 2026-10-10
Context
The budget is zero beyond domains until the pilot proves the product. The team has two always-on machines in different homes in Vietnam, each with a UPS and a public IPv4 address. Use is classroom-only for now, so short outages are acceptable. vgu-graduation exposed its homelab by port-forwarding with no edge protection (its ADR-009), which is not acceptable for children's data.
Decision
Run the API, PostgreSQL and object storage on k3s across the two home nodes. Reach them only through Cloudflare Tunnel (free), with a connector on each node: no inbound ports, no dynamic DNS, and Cloudflare's WAF and DDoS protection in front. Move DNS for both domains from Spaceship to Cloudflare. Phase 0 runs on node A; node B joins during the pilot with a PostgreSQL replica, Garage at two copies (one zone per home) and a second tunnel connector. PostgreSQL is backed up nightly to Cloudflare R2's free tier from day one. Every node uses full-disk encryption.
Alternatives considered
- Port-forwarding as in vgu-graduation: exposes home IPs and has no WAF.
- A VPS or managed PostgreSQL: better uptime, but a monthly cost before there's revenue. It's the planned move after funding.
Consequences
- An outage lasts as long as a power or ISP failure at the primary home. Two nodes cannot form an HA control plane; that needs a third.
- Cloudflare's free Universal SSL covers one subdomain level, which shapes hostnames (ADR-006).
- Cloudflare, as the TLS terminator, is a subprocessor of student data.