67 lines
3.7 KiB
Markdown
67 lines
3.7 KiB
Markdown
# 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](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 `site`s. Isolation/containers/DB/network
|
||
are per **site**; grouping (one SFTP login, recursive backup, billing) is per
|
||
**customer**. See [docs/03-naming-conventions.md](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/](docs/00-roadmap.md))
|
||
- ✅ Phase 1 — host baseline Ansible ([platform-infra/ansible/](platform-infra/ansible/README.md))
|
||
- ✅ Phase 2 — platform services (Traefik, MariaDB, Forgejo) in [platform-infra/stacks/](platform-infra/stacks/README.md)
|
||
- ✅ Phase 3 — site templates & base images in [site-templates/](site-templates/README.md)
|
||
- 🚧 Phase 4 — provisioning CLI in `control-panel/` (renders templates → deployments/, creates ZFS+DB+SFTP, `compose up`)
|
||
- ⬜ Phases 5–8 — backup/DR, observability, migration, panel
|
||
|
||
## 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
|
||
```bash
|
||
# 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.
|