# Local development only. Replace every credential outside a developer workstation. # # `pnpm doctor` loads this file's uncommitted `.env` counterpart and evaluates exactly the host # infrastructure configuration `pnpm api:start` would use, so the readiness report reflects the real # deployment without the API process running. # Required for a local workstation, and only ever correct there. Anything else — including an # unset value — is validated as production, which requires certificate-verified PostgreSQL TLS # (EKKLESIA_DATABASE_TLS_MODE defaults to verify-full) and rejects loopback/http identity origins. # The plaintext loopback DATABASE_URL below is therefore only usable with this set. NODE_ENV=development # Installed modules (ADR 0048). Unset, the checkout's own modules/ is used, as module development # and the platform's tests expect. Set, it must be an absolute path to an existing directory; # anything else stops the API and every module command with a sanitized error. The production # image sets /var/lib/ekklesia/modules. # EKKLESIA_MODULES_DIR=/absolute/path/to/modules POSTGRES_DB=ekklesia POSTGRES_USER=ekklesia POSTGRES_PASSWORD=ekklesia-development-only POSTGRES_PORT=5432 DATABASE_URL=postgresql://ekklesia:ekklesia-development-only@127.0.0.1:5432/ekklesia # Ekklesia's object-storage provider (ADR 0030). Absent S3_ENDPOINT means this installation has no # object storage, which is a complete deployment: only a module that declares a logical bucket in its # manifest is affected, and it is reported blocked rather than breaking anything. Production requires # https, exactly as the database transport requires verified TLS. # # These are host infrastructure. No module ever sees them: a module names a logical bucket and the # host resolves the binding. S3_ACCESS_KEY=ekklesia-development S3_SECRET_KEY=ekklesia-development-secret S3_ENDPOINT=http://127.0.0.1:8333 S3_PORT=8333 S3_REGION=us-east-1 S3_FORCE_PATH_STYLE=true # The origin a *browser* reaches object storage on, used only when signing temporary read URLs for # direct delivery (ADR 0031). Leave it unset whenever S3_ENDPOINT is itself reachable from a browser, # which is the case for this development stack: Compose publishes the service on loopback, so the # endpoint above serves both roles and direct delivery works with no extra configuration. # # Set it when Core reaches storage by a name a browser cannot resolve — a Compose service name such # as http://object-storage:8333, for instance — and browsers reach it through a public origin: # S3_DELIVERY_ENDPOINT=https://storage.example.org # It must be the origin the browser actually requests. An S3-compatible signature covers the request # Host, so a URL signed for one origin cannot be rewritten to another afterwards; a reverse proxy in # front of storage must therefore pass the original Host header through unchanged. The scheme is not # signed, so terminating TLS at that proxy and forwarding plaintext to the service is fine. # S3_DELIVERY_ENDPOINT= # Namespaces every physical bucket this installation owns, so several Ekklesia-compatible deployments # can share one S3-compatible service. Optional; defaults to "ekklesia". S3_BUCKET_PREFIX=ekklesia # Consumed only by the development Compose service's own bootstrap, never by Ekklesia's provider — # physical buckets are derived from a module's manifest declaration, not configured here. S3_BUCKET=ekklesia-development # Ekklesia's outbound email transport (ADR 0037). Absent EKKLESIA_SMTP_HOST means this installation # sends no email, which is a complete deployment: nothing in the platform sends any yet, and a # future feature that needs to is told so rather than crashing. # # These are host infrastructure. No module ever sees them, and no feature chooses its own sender: # the From address below is the only one this platform can send as. # # EKKLESIA_SMTP_HOST is a bare hostname — never a URL, a port, or a connection string. # EKKLESIA_SMTP_SECURITY is exactly one of: # implicit-tls TLS from the first byte, conventionally port 465 # starttls plaintext connect then a *required* upgrade, conventionally 587 (the default) # plaintext no TLS at all; development only, and production refuses it outright # EKKLESIA_SMTP_PORT is optional and defaults to the conventional port for the mode. # # Credentials are optional **as a pair**, because a relay authorized by source IP has neither. # Setting one without the other is refused rather than silently connecting anonymously. Never commit # a real password: this file is in every clone. # # A Google Workspace SMTP Relay deployment typically looks like: # EKKLESIA_SMTP_HOST= # EKKLESIA_SMTP_PORT=587 # EKKLESIA_SMTP_SECURITY=starttls # EKKLESIA_SMTP_FROM_ADDRESS=noreply@example.org # Whether it also needs a username and password depends on the relay's authorization setting in # Google Workspace Admin, which varies per deployment. 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=noreply@example.org # EKKLESIA_SMTP_FROM_NAME=Ekklesia # # EKKLESIA_SMTP_HELO_NAME is the name Ekklesia announces itself as in the SMTP EHLO command. # # Leave it unset unless a relay refuses the connection. An SMTP client has to identify itself, and # with nothing configured Nodemailer derives that from the machine hostname — substituting the # address literal [127.0.0.1] whenever the hostname is not fully qualified, which is the normal # state of a container or an unnamed VM. Some relays close the connection on that greeting with a # 421 before any message is offered, which looks exactly like the relay being unreachable. # # Set it to a fully qualified domain name your deployment owns — typically the sending domain. # No scheme, no port, no brackets, and at least one dot; anything else is refused at startup. # EKKLESIA_SMTP_HELO_NAME=example.org # Where an emailed verification or password-reset link sends a browser (ADR 0038). # # Absent means the Dashboard is served from EKKLESIA_IDENTITY_BASE_URL, which is the ordinary # same-origin production shape. Set it only when a deployment separates the two, for example an API # at https://api.example.org and the Dashboard at https://dash.example.org. It must also appear in # EKKLESIA_IDENTITY_TRUSTED_ORIGINS, or the identity system refuses the emailed link — Ekklesia # checks that at startup rather than letting every recipient discover it. # # This is the authenticated Dashboard host, never the public church website. # EKKLESIA_DASHBOARD_ORIGIN=https://dash.example.org # # Verification and password recovery need a working relay above. The initial platform-owner # bootstrap (pnpm identity:create-initial-owner) deliberately does not: it creates that one account # already verified, so a fresh server can be signed in to before any mail exists.