platform/CLAUDE.md
Bart Van Geyt 7b15fa9bca feat(ansible/zfs): support file-backed pool (+ single/mirror modes)
Add zfs_pool_mode: file|single|mirror.
- file (default): loopback disk image at zfs_pool_file_path — real ZFS with
  no spare disk, ideal for a cost-optimized test VM; wipes nothing.
- single/mirror: whole spare disk(s); mirror for production redundancy.
Guard/probe now loops over zfs_pool_disks. Update group_vars, README (modes,
prerequisites, safety), and CLAUDE.md current-focus note.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-09 03:09:38 +02:00

4.6 KiB
Raw Blame History

CLAUDE.md — heleosv2 platform

Multi-tenant web hosting platform: container-per-site + ZFS-dataset-per-site, CLI-driven provisioning, decoupled per-site backup/restore. Single bare-metal host, Docker Compose per site, no orchestrator.

Read docs/ first — it is the source of truth. Start with docs/00-roadmap.md. This file is just the orientation map so a fresh session gets up to speed cheaply.

Core philosophy

  1. The customer is the boundary — isolation, backup, restore align on it.
  2. Two levels: a customer owns many sites. Isolation/containers/DB/network are per site; grouping (one SFTP login, recursive backup, billing) is per customer. See docs/03-naming-conventions.md.
  3. Containers isolate, they don't secure by themselves — non-root FPM, read-only rootfs, per-site networks, egress filtering, least-priv DB users.
  4. Each backup stream matches its change pattern — web files via ZFS snapshot/send; DB via automysqlbackup + rsync; logs via Loki. Never fold the DB dump into the web dataset (it bloats every incremental).
  5. CLI/templates before UI. Prove the platform, then wrap it in a panel.

Status

  • Phase 0 — design docs, ADRs, scaffold (docs/)
  • Phase 1 — host baseline Ansible (platform-infra/ansible/)
  • Phase 2 — platform services (Traefik, MariaDB, Forgejo) in platform-infra/stacks/
  • Phase 3 — site templates & base images in site-templates/
  • Phase 4 — provisioning CLI heleosctl in control-panel/ (provision/deprovision/list/render/backup/restore; --dry-run; 22 tests)
  • Phase 5 — backup/DR automation in the backup Ansible role (sanoid snapshots, per-DB dump timer, optional syncoid/rsync offsite)
  • 🚧 Phase 6 — observability (Prometheus/Grafana + cAdvisor/node_exporter/Traefik metrics, Loki/Promtail, Uptime-Kuma)
  • Phases 78 — migration, customer panel

Current focus (Aug 2026)

Bringing up Phases 15 on a cost-optimized test VM (Ubuntu). ZFS is simulated via a file-backed pool (zfs_pool_mode: file, default) since the VM has no spare disk; the zfs role also supports single/mirror for a real host later. Existing box korat (Hetzner, in prod) is NOT the target — a fresh VM is. Next: finish the VM playbook run, then Phase 2 stacks on the VM (or author Phase 6 observability).

Phase 4 follow-ups (not yet done)

  • reconfigure + rotate-secret commands; git-commit of deployments/ on provision; php-fpm umask for two-way SFTP editing (see control-panel/README.md).

Repo map

Path Purpose
docs/ Architecture, ADRs, runbooks, conventions (authoritative).
platform-infra/ansible/ Phase 1 host baseline (ZFS, Docker, firewall, SSH).
platform-infra/stacks/ Phase 2 base compose projects (Traefik/MariaDB/Forgejo).
site-templates/ Dockerfiles + per-profile compose templates (Phase 3).
deployments/ Rendered per-site configs <customer>/<site>/ (GitOps state).
control-panel/ Provisioning CLI (Phase 4), panel later.

Naming quick-ref (see docs/03)

  • customer + site ids; slug = <customer>-<site> (Docker/DB key).
  • ZFS: tank/customers/<customer>/<site>/web; platform on tank/platform/*.
  • DB: db_<customer>_<site> + user u_<customer>_<site> on shared MariaDB.
  • Networks: shared proxy (edge) + platform (DB); per-site <slug>_net.

Common commands

# Phase 1 — host baseline (from platform-infra/ansible, against the VM)
ansible-galaxy collection install -r requirements.yml
ansible-playbook site.yml            # tags: base|zfs|docker|firewall|ssh

# Phase 2 — platform services (on the host, once Phase 1 is applied)
platform-infra/stacks/bootstrap-networks.sh
cd platform-infra/stacks/<svc> && cp .env.example .env && docker compose up -d

Working agreements

  • Docs are source of truth. When a design decision changes, update the relevant docs/ file and add/adjust an ADR in docs/adr/.
  • Never commit plaintext secrets. Only *.enc.* (SOPS/age) are allowed; .env is git-ignored (.env.example is committed). See .gitignore.
  • Line endings: LF for scripts/Dockerfiles/YAML (enforced by .gitattributes) — these run on Linux.
  • Commit per phase/step with a descriptive message; the repo is the memory.
  • Environment is Windows (authoring) → Linux host (runtime). Prefer the Bash tool for POSIX one-offs.