Add base Docker Compose projects under platform-infra/stacks, using the Phase 1 ZFS platform datasets and shared networks: - bootstrap-networks.sh: idempotent creation of shared `proxy` (edge) and `platform` (internal) Docker networks. - traefik: edge router with TLS/ACME (HTTP-01), global HTTP->HTTPS redirect, file-based security-headers/TLS middlewares, and a basic-auth dashboard. Docker access via a least-privilege tecnativa/docker-socket-proxy instead of mounting docker.sock directly. - mariadb: shared instance on tank/platform/mariadb, utf8mb4, tuned; not published to the host (internal `platform` network only). - forgejo: Git + container registry over HTTPS (SSH disabled to avoid extra inbound ports), SQLite backend, data on tank/platform/forgejo. Each stack ships a committed .env.example (real .env is git-ignored) and the stacks README documents bring-up order, secrets, and verification. Also add root CLAUDE.md so fresh sessions orient from files cheaply: philosophy, doc pointers, naming quick-ref, repo map, commands, agreements. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
65 lines
3.4 KiB
Markdown
65 lines
3.4 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/`
|
||
- ⬜ Phases 3–8 — site templates, provisioning CLI, 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.
|