CI / verify (pull_request) Failing after 47s
CI / infrastructure-smoke (pull_request) Skipped
CI / migration-smoke (pull_request) Skipped
CI / image-build (pull_request) Skipped
CI / deploy-smoke (same-origin) (pull_request) Skipped
CI / deploy-smoke (split) (pull_request) Skipped
The production image now contains zero feature modules and is the same for every installation. Installed modules live in module storage that one Core resolver selects from EKKLESIA_MODULES_DIR: the checkout's modules/ when unset, an absolute path that must exist when set (/var/lib/ekklesia/modules in the image). A relative, blank, missing, or unreadable configured directory fails closed with a sanitized error that never contains the value. - Host configuration reads EKKLESIA_MODULES_DIR. The API, migration plan, apply and validate, module validation, module enablement, and Doctor all resolve it the same way; the test-only API override still takes precedence. - Doctor receives Core's migrations directory explicitly instead of deriving it from the modules directory's parent. - The migration runner retains and reports the applied history of a module that is not installed, and plans and applies Core's and present modules' migrations around it. Core's history and every installed module's history stay strict: a missing or changed applied migration, or a downgrade, still fails. No down migrations, no data deletion. - deploy/Dockerfile copies no module and installs nothing for the module template; .dockerignore excludes modules/ and the build refuses a context that contains it; the runtime has an empty root-owned /var/lib/ekklesia/modules and sets EKKLESIA_MODULES_DIR. - deploy/compose.yaml bind-mounts EKKLESIA_MODULES_HOST_DIR read-only into api and migrate, with create_host_path disabled. - scripts/check-image.sh proves the image holds no modules and that a populated modules/ directory leaves its runtime file system identical; CI runs it. - The split deploy smoke now uses the same generic image: it boots with no modules, installs a self-contained test module packaged from the template (test-only), migrates and restarts, removes it (Core runs, planning reports the retained history, data survives), and restores it with its data. Docs: deploy README (module storage, install/update/remove/restore, the runtime modules target), .env.example, API configuration, module development guide, testing, workflow, security, and the architecture overview. Co-Authored-By: Claude Opus 5.5 <[email protected]>
81 lines
4.3 KiB
Bash
81 lines
4.3 KiB
Bash
# Ekklesia API and operator commands (`api` and `migrate`). Reference deployment, ADR 0044.
|
|
#
|
|
# Install as EKKLESIA_ENV_DIR/ekklesia.env (default /etc/ekklesia/ekklesia.env), owned by root with
|
|
# mode 600:
|
|
# install -o root -g root -m 600 env/ekklesia.env.example /etc/ekklesia/ekklesia.env
|
|
# Never commit the filled-in file. Generate secrets with scripts/gen-secrets.sh, and the database CA
|
|
# line with scripts/init-tls.sh.
|
|
#
|
|
# The image already sets NODE_ENV=production, EKKLESIA_API_HOST=0.0.0.0, EKKLESIA_API_PORT=3000, and
|
|
# EKKLESIA_MODULES_DIR=/var/lib/ekklesia/modules. Compose sets NODE_EXTRA_CA_CERTS and mounts module
|
|
# storage at that path. The proxy overlay sets the three EKKLESIA_CLIENT_ADDRESS_* variables. None of
|
|
# those belong here.
|
|
#
|
|
# Installed modules (ADR 0048) are read from EKKLESIA_MODULES_DIR, which must name the mounted
|
|
# directory. Move the host directory with EKKLESIA_MODULES_HOST_DIR in deploy/.env instead.
|
|
# EKKLESIA_MODULES_DIR=/var/lib/ekklesia/modules
|
|
#
|
|
# Values that are part of the reference topology are filled in; everything installation-specific is
|
|
# blank. Full reference: docs/development/api.md#required-configuration.
|
|
|
|
# --- Database (ADR 0018) ------------------------------------------------------------------------
|
|
# The host must be exactly `postgres`: the server certificate is issued for that name and
|
|
# verify-full checks it. User, password, and database must match postgres.env. Percent-encode any
|
|
# reserved character in the password. Never add sslmode or another TLS parameter to this URL.
|
|
DATABASE_URL=postgresql://<user>:<password>@postgres:5432/<database>
|
|
EKKLESIA_DATABASE_TLS_MODE=verify-full
|
|
# The installation-private CA as PEM text (not a path), on one double-quoted line with \n escapes.
|
|
# scripts/init-tls.sh prints this exact line. It is the only CA the database connection trusts.
|
|
EKKLESIA_DATABASE_CA=
|
|
|
|
# --- Identity (ADR 0011, ADR 0018, ADR 0034, ADR 0045) -----------------------------------------
|
|
# The public https origin of the API, with no path: the Ekklesia hostname in the same-origin
|
|
# topology, the API's hostname in the split one. Production rejects http and loopback origins.
|
|
EKKLESIA_IDENTITY_BASE_URL=
|
|
# Comma-separated exact origins allowed to make credentialed requests. The API's own origin is
|
|
# always trusted and need not be listed. Same-origin topology: the base URL. Split topology: the
|
|
# Dashboard's origin.
|
|
EKKLESIA_IDENTITY_TRUSTED_ORIGINS=
|
|
# At least 32 random characters. Rotating it signs every user out.
|
|
EKKLESIA_IDENTITY_SECRET=
|
|
# Same-origin topology: leave unset; the Dashboard is served from the base URL (ADR 0044).
|
|
# Split topology: the Dashboard's https origin, which must also be in the trusted origins. Emailed
|
|
# verification and reset links land here (ADR 0045).
|
|
# EKKLESIA_DASHBOARD_ORIGIN=
|
|
# Production refuses public sign-up. Leave unset.
|
|
# EKKLESIA_PUBLIC_SIGNUP_ENABLED=
|
|
|
|
# --- Client address (ADR 0017) ------------------------------------------------------------------
|
|
# Set by compose.proxy.yaml. Only a base-only deployment behind its own proxy sets these here, with
|
|
# that proxy's fixed address as the only trusted entry (deploy/README.md):
|
|
# EKKLESIA_CLIENT_ADDRESS_MODE=trusted-proxy
|
|
# EKKLESIA_CLIENT_ADDRESS_HEADER=x-forwarded-for
|
|
# EKKLESIA_CLIENT_ADDRESS_TRUSTED_PROXIES=<proxy address>/32
|
|
|
|
# --- Object storage (ADR 0030, ADR 0031) --------------------------------------------------------
|
|
# The API reaches SeaweedFS over HTTPS on the private network; production storage must be https.
|
|
S3_ENDPOINT=https://object-storage:8443
|
|
# The https origin browsers fetch signed object URLs from: the storage hostname on the proxy.
|
|
S3_DELIVERY_ENDPOINT=
|
|
# Must match object-storage.env.
|
|
S3_ACCESS_KEY=
|
|
S3_SECRET_KEY=
|
|
S3_REGION=us-east-1
|
|
S3_FORCE_PATH_STYLE=true
|
|
S3_BUCKET_PREFIX=ekklesia
|
|
|
|
# --- Outbound email (ADR 0037), optional --------------------------------------------------------
|
|
# Without a relay, email verification and password recovery cannot deliver. See
|
|
# docs/development/email.md.
|
|
# EKKLESIA_SMTP_HOST=
|
|
# EKKLESIA_SMTP_PORT=587
|
|
# EKKLESIA_SMTP_SECURITY=starttls
|
|
# EKKLESIA_SMTP_USERNAME=
|
|
# EKKLESIA_SMTP_PASSWORD=
|
|
# EKKLESIA_SMTP_FROM_ADDRESS=
|
|
# EKKLESIA_SMTP_FROM_NAME=Ekklesia
|
|
# EKKLESIA_SMTP_HELO_NAME=
|
|
|
|
# --- Module secrets (ADR 0029), as installed modules declare them --------------------------------
|
|
# EKKLESIA_MODULE_SECRET__<MODULE_ID>__<KEY>=
|