feat(deploy): add the reference deployment Compose project
CI / verify (pull_request) Successful in 54s
CI / infrastructure-smoke (pull_request) Successful in 21s
CI / migration-smoke (pull_request) Successful in 1m48s
CI / image-build (pull_request) Successful in 27s
CI / deploy-smoke (pull_request) Successful in 42s
CI / verify (pull_request) Successful in 54s
CI / infrastructure-smoke (pull_request) Successful in 21s
CI / migration-smoke (pull_request) Successful in 1m48s
CI / image-build (pull_request) Successful in 27s
CI / deploy-smoke (pull_request) Successful in 42s
Implement ADR 0044's reference deployment as a base Compose file plus overlays, so an installation that already runs a proxy can use the base alone. - compose.yaml: api, postgres, object-storage, and the operator-only migrate (profile ops, plan by default). No published port. api and migrate run init, read-only, tmpfs /tmp, cap_drop ALL, no-new-privileges. postgres is only on the internal data network. - TLS everywhere from one installation-private CA: PostgreSQL TLS 1.3 only, with pg_hba rejecting every non-TLS connection, and the API on verify-full via EKKLESIA_DATABASE_CA (PEM text). SeaweedFS serves S3 over HTTPS (ADR 0030 requires https in production), trusted by the API through NODE_EXTRA_CA_CERTS. No Core change. - compose.proxy.yaml + Caddyfile.example: Caddy pinned by digest, ACME HTTP-01 (DNS-01 documented), routes /, /api/*, /display/*, /assets/* to api and refuses everything else; the storage hostname preserves Host. The API trusts exactly the proxy's fixed /32 on an edge network whose dynamic range excludes the fixed addresses; Caddy overwrites X-Forwarded-For and strips caller-supplied forwarding headers. - compose.tunnel.yaml: cloudflared pinned by digest, token from its own env file; Caddy honors CF-Connecting-IP only from its fixed address. - Four per-service root-owned env files, examples with no values; scripts/init-tls.sh (idempotent, never overwrites a key) and scripts/gen-secrets.sh (prints only). - CI: pnpm deploy:config in ci:verify for all three combinations, and a deploy-smoke job (scripts/smoke-deploy.sh) proving readiness, the Dashboard, signed storage delivery, the client-address chain, initial owner sign-in/out, verify-full database TLS, and Doctor through the proxy, against disposable services. tests/deploy.test.ts pins the structural guarantees. - ADR 0044 (still Proposed) amended to match: API-to-storage HTTPS, DNS-01 needs a custom Caddy build and tunnel-only needs DNS-01, the tunnel's origin TLS settings live in the Cloudflare dashboard, port 80 serves HTTP-01, and secrets are one env file per service. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
b593abe7a5
commit
167b4c4f14
@@ -463,11 +463,12 @@ Until that exists, the trusted-code model above is the security model.
|
||||
|
||||
## Current deployment state
|
||||
|
||||
As of this branch, **Ekklesia is not deployed**. There is no production API instance, no reverse
|
||||
proxy, no public listener, and no deployment automation in this repository — no deploy script, no
|
||||
CI deployment step, no container publish, no orchestration manifest. The repository can **build** a
|
||||
production image ([`deploy/`](../../deploy/README.md)), and CI builds it without modules on every
|
||||
change, but nothing pushes, publishes, or runs it anywhere. No `.env` has ever been committed; only
|
||||
As of this branch, **Ekklesia is not deployed**. There is no production API instance, no running
|
||||
reverse proxy, no public listener, and no deployment automation in this repository — no deploy
|
||||
script, no CI deployment step, no container publish. The repository provides a **reference deployment**
|
||||
([`deploy/`](../../deploy/README.md)): a production image and the Compose project that runs it, which
|
||||
CI builds and smoke-tests end to end on every change against disposable services. Nothing pushes,
|
||||
publishes, or runs it against a real installation. No `.env` has ever been committed; only
|
||||
`.env.example`, which the image build context excludes.
|
||||
|
||||
Two production defaults are relevant but are **not** by themselves a deployment guarantee:
|
||||
@@ -490,8 +491,9 @@ outstanding.
|
||||
|
||||
1. The reverse proxy forwards the Dashboard and `/api` on the intended origin, or an explicitly
|
||||
split origin is covered by the exact trusted-origin/CORS configuration. `apps/api` serves the
|
||||
built Dashboard itself at `/` ([API § Dashboard host](api.md#dashboard-host)); the repository
|
||||
does not yet supply the proxy deployment.
|
||||
built Dashboard itself at `/` ([API § Dashboard host](api.md#dashboard-host)), and the
|
||||
reference deployment's proxy routes it ([deploy/README.md](../../deploy/README.md#launch-checklist)
|
||||
maps every item here to its configuration).
|
||||
2. The origin port is unreachable from the public Internet.
|
||||
3. The origin port is also unreachable from any untrusted network/VLAN — only the intended private
|
||||
proxy path connects. Security must not depend on an unpublished DNS name or origin IP.
|
||||
|
||||
Reference in New Issue
Block a user