Edgeweir
Reference

Environment variables

Variables the console process reads, with defaults and validation, plus the host variables used by the Compose files.

Loading and validation

  • The process reads and validates every variable once at startup. An invalid value stops the process; the log line starts with invalid configuration: and names the variables.
  • Recreate the container after a change: docker compose up -d. docker compose restart does not apply new values.
  • An empty BETTER_AUTH_SECRET, EDGEWEIR_NODE_API_URL, EDGEWEIR_NODE_API_WEBSOCKET, NODE_API_HOST, or EDGEWEIR_NODE_RELEASE_BASE_URL counts as unset; an empty value of any other variable is validated as is, e.g. ROLE= is invalid.
  • The Default column is the process default. Values set by the image or a Compose file are given in the Description column.
  • Fallback: a value saved in System settings wins; clearing the saved value restores the variable.
  • Template with comments: .env.example.

Required

With compose.yml or compose.baota.yml, DATABASE_URL is built from the Compose host variable POSTGRES_PASSWORD.

VariableDefaultDescription
EDGEWEIR_MASTER_KEYNoneMaster key. Canonical base64 (standard or URL-safe alphabet) of at least 32 bytes; the console refuses to start on any other character, such as a space or a quote, or on fewer than 32 bytes. Generate it with openssl rand -base64 32 and use the output as is (keep /, +, and =). A key other than the one the database's secrets were encrypted with stops the console with EDGEWEIR_MASTER_KEY does not match this database; restore the original key, or, when rotating it, set the original as EDGEWEIR_MASTER_KEY_PREVIOUS, rather than setting BETTER_AUTH_SECRET. Envelope-encrypts private keys, DNS API keys, and other secrets at rest, and derives the session secret. Losing it makes encrypted data unrecoverable; back it up separately from the database.
EDGEWEIR_MASTER_KEY_FILEUnsetFile holding the master key (for example a Docker secret), instead of EDGEWEIR_MASTER_KEY; its trailing newline is ignored and the content is checked like EDGEWEIR_MASTER_KEY. The console refuses to start when EDGEWEIR_MASTER_KEY is also set to a non-empty value or the file is empty or cannot be read. The Compose templates do not pass it; see Master key file.
DATABASE_URLNonePostgreSQL 18 connection string. At startup the console waits up to 60 seconds for the database, then runs migrations. compose.yml and compose.baota.yml build it from POSTGRES_PASSWORD and ignore the .env value; compose.baota-host.yml takes it from .env, or reads it from DATABASE_URL_FILE set in compose.override.yml (Read from files).
EDGEWEIR_PUBLIC_URLhttp://localhost:3000URL browsers use to reach the console; behind a reverse proxy, the proxy URL. Format http(s)://host[:port], without path, query, fragment, user name, or password; a trailing / and the default port are dropped. Any other value stops the console at startup. Used for the trusted origin of the authentication endpoints, the Secure attribute of session cookies (with https://), the passkey RP ID (host name), the servers entry of the OpenAPI document, the console URL in /install.sh, links in alert notifications, and the default host of EDGEWEIR_NODE_API_URL. The default only suits local access: node install commands and alert links would point to localhost. A local or private address, or a public http:// one, logs a warning at startup; see Adding nodes.

Session secret

VariableDefaultDescription
BETTER_AUTH_SECRETDerived from the master keySecret that signs sessions and encrypts two-factor secrets; at least 32 characters. Unset: derived from the master key with HKDF-SHA256 (parameters in SECURITY.en.md); it keeps its value when the master key is rotated. A deployment that has set it must keep the value: removing it stops the console from starting; a new value starts the console with a warning, ends every session, and makes enrolled two-factor secrets unreadable.

Master key rotation

VariableDefaultDescription
EDGEWEIR_MASTER_KEY_PREVIOUSUnsetThe master key before a rotation; it only decrypts. Same rules as EDGEWEIR_MASTER_KEY; the same key as that one stops the console. At startup data it encrypted is accepted, and every envelope it sealed in the database is encrypted again with EDGEWEIR_MASTER_KEY; the master key rotation log line gives the counts. Once none is left the log says no envelope uses EDGEWEIR_MASTER_KEY_PREVIOUS any more: remove it and restart the console; remove it then and restart. While envelopes still use it the log says envelopes still use EDGEWEIR_MASTER_KEY_PREVIOUS: keep it set. Revision receipts held by nodes keep verifying while it is set; nodes get receipts of the new key with their next configuration fetch. Without BETTER_AUTH_SECRET, the session secret stays the one derived from the old key, stored in system_setting sealed with the new key: sessions and two-factor secrets are not affected. Steps: Rotating the master key.

Read from files

These variables can be read from files instead (for example Docker secrets): <variable>_FILE names the file, whose content is the value; its trailing newline is ignored and the value is checked like the variable itself. The console refuses to start when the variable is also set to a non-empty value, or the file is empty or cannot be read; an empty _FILE counts as unset. The Compose templates do not pass the _FILE variables; mounting and setting them: Other secret files.

VariableInstead of
EDGEWEIR_MASTER_KEY_FILEEDGEWEIR_MASTER_KEY; see Required
EDGEWEIR_MASTER_KEY_PREVIOUS_FILEEDGEWEIR_MASTER_KEY_PREVIOUS
DATABASE_URL_FILEDATABASE_URL: the whole connection string of an external database
BETTER_AUTH_SECRET_FILEBETTER_AUTH_SECRET
EDGEWEIR_CLICKHOUSE_PASSWORD_FILEEDGEWEIR_CLICKHOUSE_PASSWORD; the Compose templates give it a default, so set it to "" in compose.override.yml

Addresses and network

VariableDefaultDescription
EDGEWEIR_NODE_API_URLhttps://<host of EDGEWEIR_PUBLIC_URL>:<NODE_API_PORT>; with EDGEWEIR_NODE_API_WEBSOCKET=true, wss://<host[:port] of EDGEWEIR_PUBLIC_URL>URL nodes use to reach the node channel while no URL is saved under "Node channel" in System settings, in the form https://host[:port] (the node channel port), or wss:// or ws://host[:port] (the WebSocket entry on the web port; see The node channel's WebSocket entry), with the same rules as EDGEWEIR_PUBLIC_URL. Used as --server in node install commands; its host goes into the node channel server certificate. The default uses the process NODE_API_PORT (8443 in the image), not Compose's EDGEWEIR_NODE_API_PORT; when the host port is not 8443 or nodes connect through another address, enter the URL in System settings or set this variable; see Node channel URL and certificate.
EDGEWEIR_NODE_API_WEBSOCKETfalsetrue, 1, yes, on turn it on; false, 0, no, off turn it off (case-insensitive). When on: without EDGEWEIR_NODE_API_URL, the default node channel URL is wss://<host[:port] of EDGEWEIR_PUBLIC_URL> (ws:// when EDGEWEIR_PUBLIC_URL is http://), and the WebSocket entry /node-channel on the web port is always open. For platforms that only forward HTTP (such as Render). Any other value stops the console at startup.
EDGEWEIR_NODE_API_HOSTNAMESEmptyExtra names (DNS names or IPs) for the node channel server certificate, comma separated. The certificate always includes localhost, 127.0.0.1, ::1, the machine host name (the container host name in a container), the host of EDGEWEIR_NODE_API_URL, and the hosts of node channel URLs saved in System settings. Changes to this variable apply after a restart; enrolled nodes verify these names.
EDGEWEIR_TRUSTED_PROXIESEmptyTrusted reverse proxies as IPs or CIDRs, comma separated. X-Forwarded-For and X-Real-IP are used only from these addresses, for audit log IPs and sign-in rate limiting. Empty: the TCP peer is the client. An entry that is not an IP or CIDR stops the console from starting. compose.baota-host.yml defaults to 127.0.0.1,::1. Configuration: Ports, reverse proxy, and trusted proxies.
EDGEWEIR_OUTBOUND_ALLOW_CIDRSEmptyPrivate or special-purpose ranges (CIDRs, separated by commas or whitespace) the console may reach for destinations saved in the web console: alert notification channels, SMTP, and the node release source. Empty: public addresses only. Values saved in the web console cannot widen this boundary. A release source set through an environment variable is not bound by it. The console refuses to start on an entry that is not an IP address or CIDR range.

Analytics

The ClickHouse variables apply only with EDGEWEIR_ANALYTICS=clickhouse. The analytics profile of compose.yml creates the ClickHouse database and user from EDGEWEIR_CLICKHOUSE_DATABASE, EDGEWEIR_CLICKHOUSE_USER, and the same password.

VariableDefaultDescription
EDGEWEIR_ANALYTICSliteStorage for access logs and per-minute statistics: lite (PostgreSQL) or clickhouse. Switching does not migrate history. Shown as "Analytics" in System settings. Behavior: Access logs and AccessKey.
EDGEWEIR_CLICKHOUSE_URLhttp://clickhouse:8123ClickHouse HTTP interface. http or https only, without user name, password, query, or fragment. compose.baota.yml defaults to http://host.docker.internal:8123 (the host; ClickHouse must listen on the Docker bridge address), compose.baota-host.yml to http://localhost:8123.
EDGEWEIR_CLICKHOUSE_DATABASEedgeweirDatabase name; must match ^[A-Za-z_][A-Za-z0-9_]{0,63}$.
EDGEWEIR_CLICKHOUSE_USERedgeweirUser name, sent in the X-ClickHouse-User header.
EDGEWEIR_CLICKHOUSE_PASSWORDEmptyPassword, sent in the X-ClickHouse-Key header. When unset, the Compose files use CLICKHOUSE_PASSWORD, then edgeweir.

Certificates and DNS

VariableDefaultDescription
EDGEWEIR_ACME_DIRECTORYEmptyACME directory URL for every certificate; overrides the CA chosen per certificate. When set, Request certificate shows this directory instead of the CA and EAB fields, the console logs a warning at startup, and each certificate records the directory it was issued from, which its ARI renewal windows are read from. Private PKI and tests only; ACME accounts do not move between directories. Empty: Let's Encrypt or ZeroSSL, chosen per certificate (HTTPS and certificates).
EDGEWEIR_ACME_CA_FILEEmptyPath of a PEM file the certificate helper uses to verify the ACME directory's TLS certificate. Used with EDGEWEIR_ACME_DIRECTORY.
EDGEWEIR_SMTP_CA_FILEEmptyFallback for Alerts → SMTP → "CA certificates (PEM)". CA for SMTP TLS (path of a PEM file), used only when the SMTP settings hold no CA. Empty: the system trust store.
EDGEWEIR_DNS_TEST_ENDPOINTEmptyAddress of the local DNS simulator for integration tests; enables the test DNS provider. Never set it for real providers.

Node releases

VariableDefaultDescription
EDGEWEIR_NODE_RELEASE_BASE_URLEmptyFallback for System settings → Node release source. Base URL node upgrades read release manifests from, at <base>/v<version>/checksums.txt. http or https only, without user name, password, query, or fragment; at most 2048 characters. Empty: https://github.com/marvinli001/edgeweir-node/releases/download.
EDGEWEIR_DOWNLOADS_DIRUnsetDirectory of release files served at /downloads/*, from which install.sh downloads node packages and cosign. Unset: /downloads/* returns 404 and install.sh downloads from GitHub. Directory layout: Adding nodes.

Runtime

VariableDefaultDescription
ROLEallProcess role: all, app, or worker. Components per role: Deployment overview.
HOST0.0.0.0Listen address of the web UI and API. compose.baota-host.yml: 127.0.0.1.
PORT3000Listen port of the web UI and API, 1–65535.
NODE_API_HOSTValue of HOSTListen address of the node channel. compose.baota-host.yml: from EDGEWEIR_NODE_API_HOST, default 0.0.0.0.
NODE_API_PORT8443Listen port of the node channel.
LOG_LEVELinfodebug, info, warn, or error. Logs are one JSON object per line.
NODE_ENVdevelopment (image: production)development, production, or test. production enables rate limiting of the authentication endpoints, with counters in PostgreSQL.
EDGEWEIR_WEB_DIST<directory of main.js>/../webDirectory of the built web UI; resolves to /app/dist/web in the image. Not used by pnpm dev.
EDGEWEIR_CERTD_BINedgeweir-certd (image: /usr/local/bin/edgeweir-certd)Path of the certificate helper; looked up in PATH when it contains no /. From source, build it with cd helpers/certd && go build -o bin/edgeweir-certd . and set its absolute path.
EDGEWEIR_VERSIONdev (image: build version)Version the process reports in /healthz, the OpenAPI document, and "Version" in System settings. The image build sets the rolling version <YYYYMMDD>-<commit>; do not override it in the container environment. Compose uses a host variable of the same name to pick the image tag; see Compose host variables.

Compose host variables

Compose reads these variables on the host (.env or the shell environment) to interpolate the Compose files; the console process does not read them. For the unattended variables of deploy.sh, see deploy.sh reference.

VariableDefaultDescription
EDGEWEIR_VERSIONlatestImage tag to pull: ghcr.io/marvinli001/edgeweir:<EDGEWEIR_VERSION>. Rolling tags are <YYYYMMDD>-<commit>; @sha256:<digest> may be appended. See Versions, upgrades, and rollback.
EDGEWEIR_HTTP_PORT3000Host port of the web console. compose.yml: a port publishing spec, may include a bind address, default 127.0.0.1:3000 (ports Docker publishes bypass ufw and firewalld); 3000 publishes it on every interface. compose.baota.yml: number only, bound to 127.0.0.1. compose.baota-host.yml: number only, used as PORT.
EDGEWEIR_NODE_API_PORT8443Host port of the node channel. compose.yml and compose.baota.yml: a port publishing spec, may include a bind address. compose.baota-host.yml: number only, used as NODE_API_PORT.
EDGEWEIR_NODE_API_HOST0.0.0.0compose.baota-host.yml only: listen address of the node channel, used as NODE_API_HOST; 127.0.0.1 behind an nginx stream passthrough on the same host.
POSTGRES_PASSWORDNonePassword of the bundled PostgreSQL; compose.yml and compose.baota.yml build DATABASE_URL from it, and refuse to start without it (deployments created without it used edgeweir). Must be URL-safe: openssl rand -hex 24. The PostgreSQL image applies it only to an empty data directory; changing it later does not change the existing password.
COMPOSE_PROFILESEmptyProfiles Compose enables, comma separated. analytics: the ClickHouse service of compose.yml; set in .env, every docker compose and deploy.sh command includes it without --profile.
CLICKHOUSE_PASSWORDedgeweirClickHouse password when EDGEWEIR_CLICKHOUSE_PASSWORD is unset, shared by the console and the ClickHouse container of the analytics profile.
DEV_POSTGRES_PORT5432compose.dev.yml: port of the development database on 127.0.0.1.

Variables passed to the container

The Compose files pass the remaining console variables as ${VARIABLE:-default}. The table lists fixed values and variables that are not passed; a variable that is not passed has no effect in .env; add it to the service's environment when needed.

Compose fileFixed valuesNot passed
compose.ymlROLE=allThe _FILE variables of Read from files, HOST, PORT, NODE_API_HOST, NODE_API_PORT, NODE_ENV, EDGEWEIR_WEB_DIST, EDGEWEIR_CERTD_BIN, EDGEWEIR_DNS_TEST_ENDPOINT, EDGEWEIR_VERSION
compose.baota.ymlROLE=allSame as compose.yml, plus LOG_LEVEL and EDGEWEIR_DOWNLOADS_DIR
compose.baota-host.ymlROLE=all, HOST=127.0.0.1; PORT, NODE_API_HOST, and NODE_API_PORT from the host variables EDGEWEIR_HTTP_PORT, EDGEWEIR_NODE_API_HOST (default 0.0.0.0), and EDGEWEIR_NODE_API_PORTThe _FILE variables of Read from files, NODE_ENV, EDGEWEIR_WEB_DIST, EDGEWEIR_CERTD_BIN, EDGEWEIR_DNS_TEST_ENDPOINT, EDGEWEIR_VERSION, LOG_LEVEL, and EDGEWEIR_DOWNLOADS_DIR
Edit on GitHub

On this page