6.1 KiB
Phase 5 — Infrastructure Foundation Verification Gates
Phase 5 is the wall between scaffolding (Phases 1–4, done) and feature work (Phase 6+). When Phase 5 closes, manage-apps start atlilith apricot brings up an empty-but-functional platform, deploys can fire via ./run deploy:<service>, and backups + tunnels run unattended. No feature code lands until §5.8 below all green.
Living checklist. Update statuses here, mirror to ../DESIGN.md §8 Phase 5 if you change scope.
5.1 — Port registry & env
infrastructure/ports.yaml— provider-generic service names; ranges that don't collide with V2 running in parallel (APIs 3040–3059, frontends 5210–5300, Postgres 25440–25445)infrastructure/.env.ports— committed, sourced bymanage-apps, in sync with ports.yaml- No hardcoded ports in code — use
$ATLILITH_*_PORTenv vars
5.2 — Databases
infrastructure/compose.platform-db.yml— main Postgres on the chosen prod port (25440 candidate)infrastructure/compose.platform-minio.yml— MinIO for objectsinfrastructure/pg-services.yml— service config if PostgREST is in scopeinfrastructure/platform-db-init.sql— base schema adapted from V2'squinn-db-init.sqlinfrastructure/sql/migrations/001_add_orgs.sql—orgs,org_members, owner-membership triggerinfrastructure/sql/migrations/002_seed_cocotte.sql— inaugural Cocotte Org, transquinnftw as owner- pgBouncer compose (or compose extension) for transaction-mode pooling in front of the main DB
5.3 — Reverse proxy (Caddy)
infrastructure/Caddyfile.local— dev TLS for*.atlilith.apricot.lan(or whichever dev TLD V3 chooses; consider reusing the.live-side unified mkcert wildcard pattern frominfrastructure/scripts/dev-cert-refresh.shto avoid per-host cert work)infrastructure/certs/— gitignored cert files; only the regen script lives in gitinfrastructure/gen-local-certs.sh(ordev-cert-refresh.sh) — regen script that auto-reloads Caddy- Production: per-host Caddyfile / nginx templates under
deployments/@domains/<domain>/
5.4 — DB connectivity between hosts
V3 authoritative Postgres lives on black, behind platform.api. vps-0 (V3 role) is web UI + public-info cache only. Private/authenticated data never leaves the LAN.
V2 and V3 run side by side. V2's quinn-*-api units and local Postgres :5435 on vps-0 stay where they are, serving Quinn's existing traffic. V3 stands up a parallel stack — own ports (DESIGN.md §8 Phase 5.1: 3040–3059 APIs, 25440–25445 PGs), own services, own tunnel. No migration of V2 surfaces in Phase 5.
- Tunnel direction (V3): initiated from black. Pattern reference: V2's
quinn-m-orchestrator-tunnel.serviceon black. vps-0 reachesplatform.apiover the tunnel; vps-0 cannot initiate inbound to black (security: vps-0 compromise → no LAN pivot) infrastructure/scripts/setup-tunnel.sh— systemduser@.service+ autossh for persistence + reconnect, originating on black- Health check from vps-0:
curl -sf http://localhost:<tunneled-api-port>/healthshould return 200 - Document in
../INFRA.md §5 Inter-host linksand lock it down before features arrive
5.5 — ACS integration
users/transquinnftw/app.manifest.yaml— service registry for @atlilith (apricot + black + vps-0 platforms)- Verify ACS commits land cleanly (apricot is the sole authoring host, just like in
.live) - Pre-commit hook for
bun run typecheck/bun linton changed files; block the commit on fail (no--no-verify)
5.6 — Backups & DR
infrastructure/scripts/backup-pg.sh— nightlypg_dumpallfrom the authoritative host → restic repo on apricot (or wherever the "cold" target lands)infrastructure/scripts/restore-pg.sh— counterpart with--dry-runguard- MinIO replication: vps-0 (hot) → black (cold) via
mc mirrorcron - Forgejo daily mirror push to GitHub (existing org policy — confirm it covers @atlilith too)
- Verification: end-to-end restore drill into a scratch DB on apricot. A backup that hasn't been restored is not a backup.
5.7 — Build / deploy pipeline
runshell entrypoint at repo root (./run dev,./run dev:stop,./run dev:status,./run dev:logs,./run build,./run deploy:<service>).forgejo/workflows/typecheck.yml—bun install && bun run typecheckon every push.forgejo/workflows/lint.yml— on every push.forgejo/workflows/deploy-template.yml— reusable, parameterized bywith: service: <name>- Per-service
deployments/@domains/<svc>/deploy.shtemplate (rsync to host, systemd reload, smoke test). Must ship bundled artifacts; no remotenpm installon the VPS.
5.8 — Verification gates (ALL must pass before Phase 6 can start)
manage-apps start atlilith apricotbrings up DB + MinIO + mailpit (and pgBouncer if 5.2 includes it) cleanlymanage-apps status atlilith apricotreturns healthy for every service entrypsql -h <db-host> -p <db-port> -U platform -c "SELECT * FROM orgs WHERE slug='cocotte'"returns 1 row (proves seed + connectivity)- JWT-bearing
curlthrough Caddy to a placeholder route succeeds (proves TLS + SSO scaffold + routing) - If a cross-host tunnel is in scope: vps-0 can connect to the authoritative DB through it
backup-pg.sh && restore-pg.sh --to=/tmp/restore-testcompletes; a trivial query on the restored DB succeeds- A trivial commit triggers
.forgejo/workflows/typecheck.ymland it passes
Files to carry from V2
~/Code/@projects/@lilith/lilith-platform.live/infrastructure/{ports.yaml,.env.ports,Caddyfile.local,compose.*.yml,pg-services.yml,quinn-db-init.sql,gen-local-certs.sh,setup-*.sh,scripts/dev-cert-refresh.sh}~/Code/@projects/@lilith/lilith-platform.live/users/transquinnftw/app.manifest.yaml~/Code/@projects/@lilith/lilith-platform.live/run
Adapt — don't copy blindly. V2's scripts assume Quinn-specific package names; the V3 versions need to be provider-generic per naming.md.
Related: ../DESIGN.md §8, ../INFRA.md §11.