Bump the root and every platform workspace package from 0.1.0 to 0.1.1, so
the platform reports the version the v0.1.1 tag will carry. Module discovery
checks compatibility.platform against the root version and
compatibility.moduleSdk against @ekklesia/module-sdk; both stay inside every
existing ^0.1.0 range, so no module needs a new range. Everything since v0.1.0
is additive (health endpoints, Dashboard serving, production dependency
declarations, the deployment image and Compose project).
templates/module keeps 0.1.0: it is a module, versioned on its own, and its
manifest, source, and tests carry its own product version.
Mark ADR 0044 Accepted. Slices 1-4 are implemented and proven by CI's image
build and deploy smoke; slice 6 (scheduled backups and the restore
procedure) remains its open item.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
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]>
A module that imports a package at run time without declaring it a
production dependency now fails the image build instead of the API's
startup, since the runtime receives production dependencies only.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Add deploy/Dockerfile and .dockerignore (ADR 0044): one image for the
api service and every operator-run CLI, built from an already-assembled
workspace (the platform plus whatever modules/<id> the context holds).
- node:24.18.0-trixie-slim pinned by index digest; pnpm via Corepack at
the root packageManager version.
- Build stage: frozen install, modules:validate, migrations:validate,
build. Runtime: production-only node_modules plus every dist/, core
migrations, and each module directory, in the repository layout the
API and CLIs resolve paths from; root-owned, run as node.
- NODE_ENV=production and EKKLESIA_API_HOST=0.0.0.0 inside the image
only; the platform default stays 127.0.0.1. Configuration comes only
from the environment; no .env enters the context or any layer.
- HEALTHCHECK on /api/v1/health/ready with Node's fetch; OCI labels for
source, revision, and version.
- CI builds the image without modules: build only, no credentials, no
push.
- deploy/README.md documents the image, the read-only production
posture (verified), init: true, and the exact CLI commands.
Co-Authored-By: Claude Opus 5.5 <[email protected]>