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]>
47 lines
2.5 KiB
Bash
47 lines
2.5 KiB
Bash
# Non-secret settings for the reference deployment's Compose project. Copy to deploy/.env, which
|
|
# Compose reads automatically from this directory. Nothing here is a secret; secrets live in the
|
|
# per-service files under EKKLESIA_ENV_DIR.
|
|
|
|
# Which Compose files make up this installation, so that every plain `docker compose …` command
|
|
# run from this directory, operator commands through `migrate` included, sees the same services and
|
|
# settings as the running stack. Add compose.tunnel.yaml if you use the tunnel connector. Without
|
|
# the proxy overlay here, Doctor checks a `migrate` that lacks the API's client-address settings.
|
|
COMPOSE_FILE=compose.yaml:compose.proxy.yaml
|
|
|
|
# The image to run, by registry, name, and tag (or digest). Required.
|
|
EKKLESIA_IMAGE=
|
|
|
|
# Where the root-owned, mode-600 env files and the TLS directory live on the host.
|
|
EKKLESIA_ENV_DIR=/etc/ekklesia
|
|
EKKLESIA_TLS_DIR=/etc/ekklesia/tls
|
|
|
|
# Installed modules (ADR 0048): the host directory mounted read-only into `api` and `migrate` at
|
|
# /var/lib/ekklesia/modules. It must already exist; Compose never creates it. Create it once, owned
|
|
# by root, before the first `up`:
|
|
# sudo install -d -o root -g root -m 755 /var/lib/ekklesia/modules
|
|
# EKKLESIA_MODULES_HOST_DIR=/var/lib/ekklesia/modules
|
|
|
|
# --- compose.proxy.yaml ---------------------------------------------------------------------------
|
|
# The Ekklesia hostname and the storage hostname (signed object URLs). In the default same-origin
|
|
# topology (Caddyfile.example) EKKLESIA_HOSTNAME serves the Dashboard, the API, and displays.
|
|
EKKLESIA_HOSTNAME=
|
|
EKKLESIA_STORAGE_HOSTNAME=
|
|
# The split topology only (ADR 0045, Caddyfile.split.example): the Dashboard's own hostname, while
|
|
# EKKLESIA_HOSTNAME is the API's and the displays'. Both must share one registrable domain, for
|
|
# example dash.example.org and api.example.org. Leave empty for the same-origin topology.
|
|
EKKLESIA_DASHBOARD_HOSTNAME=
|
|
# Contact address for the ACME account (certificate expiry notices).
|
|
EKKLESIA_ACME_EMAIL=
|
|
# EKKLESIA_CADDYFILE=./Caddyfile
|
|
# EKKLESIA_PUBLISH_ADDRESS=0.0.0.0
|
|
# EKKLESIA_HTTP_PORT=80
|
|
# EKKLESIA_HTTPS_PORT=443
|
|
|
|
# The edge network. Change the subnet only if it collides with one already on the host. Docker
|
|
# assigns dynamic addresses only from EKKLESIA_EDGE_DYNAMIC_RANGE (the lower half); the proxy and
|
|
# the tunnel connector take fixed addresses from the upper half, so nothing else can ever hold them.
|
|
# EKKLESIA_EDGE_SUBNET=10.249.250.0/24
|
|
# EKKLESIA_EDGE_DYNAMIC_RANGE=10.249.250.0/25
|
|
# EKKLESIA_PROXY_ADDRESS=10.249.250.254
|
|
# EKKLESIA_TUNNEL_ADDRESS=10.249.250.253
|