Skip to content

Configuration reference

Checkstack is configured almost entirely through environment variables. The platform reads them once at process start (or on the first request that touches them) and there is no runtime reload. To change a value, restart the container.

This page is the authoritative list. If you are just looking for the minimum required to boot, see Run Checkstack with Docker and come back here when you need detail.

VariableRequiredDefaultWhat it does
BASE_URLyesnoneThe exact public URL operators type into the browser to reach Checkstack (e.g. http://192.168.1.10:3000, https://status.example.com). Used for CORS, OAuth redirects, SAML reply URLs, OpenAPI server URL, notification links, and the runtime config endpoint at /api/config. Must match the address you actually use; a mismatch silently breaks SSO redirects and shows a blank UI.
NODE_ENVnodevelopmentSet to production for JSON-formatted logs and to disable the dev log files under .dev/logs/. Also blocks CHECKSTACK_DEV_AUTH=true (it throws on boot when set in production).
CHECKSTACK_FRONTEND_DISTno (set by Docker image)unsetAbsolute path to the built frontend dist/ directory. The official Docker image sets it to /app/core/frontend/dist. If you run the backend without static assets, leave this unset and serve the frontend separately.
INTERNAL_URLnofalls back to BASE_URL or http://localhost:3000URL used for backend-to-backend RPC inside the cluster. Set this to a cluster-internal address (e.g. a Kubernetes service name like http://checkstack-svc:3000) when running multiple replicas so internal traffic skips the external load balancer.
VariableRequiredDefaultWhat it does
DATABASE_URLyesnonePostgreSQL connection string used by every backend package (postgresql://user:pass@host:5432/db). All plugin schemas live in this one database; per-plugin tables are isolated via PostgreSQL schemas (plugin_<id>). No extensions are required. Postgres 16 is the version shipped in the reference compose file.

Checkstack does not support SQLite. The platform relies on Postgres-specific features (JSONB, schema namespacing, LISTEN/NOTIFY style queueing via plugins). Any reachable Postgres 14+ instance works; managed services like Neon or Supabase are fine.

VariableRequiredDefaultWhat it does
BETTER_AUTH_SECRETyesnoneSigns session cookies and OAuth state. Must be at least 32 characters. Used by core/auth-backend and the SAML plugin. Treat this like a JWT signing key: rotating it logs every user out.
PUBLIC_URLno (SAML only)falls back to BASE_URLOptional override the SAML plugin uses to build identity-provider callback URLs. Only set this if the public URL exposed to your IdP differs from BASE_URL (rare).

For the strategy-by-strategy walkthrough (credential, GitHub OAuth, SAML, LDAP, group mapping) see Authentication strategies.

VariableRequiredDefaultWhat it does
ENCRYPTION_MASTER_KEYyesnone64-character hex string (32 bytes) used as the AES-256-GCM key for every secret stored in the database: OAuth client secrets, integration API tokens, satellite tokens, etc. Without it, the platform refuses to boot any feature that stores a secret. See Secret encryption for generation and rotation details.
VariableRequiredDefaultWhat it does
LOG_LEVELnoinfoWinston log level. One of error, warn, info, debug. Setting debug is verbose but useful when diagnosing plugin install or queue lag issues.
DEBUGnounsetOnly honoured by the satellite agent. Any non-empty value enables [satellite:debug] lines on stdout.

These variables only apply when you are developing a plugin locally; never set them in production.

VariableRequiredDefaultWhat it does
CHECKSTACK_DEV_PLUGIN_PATHnounsetAbsolute path to a plugin directory whose default export is a BackendPlugin. Setting this skips filesystem discovery and loads only that plugin plus core services. Used by bunx @checkstack/scripts dev.
CHECKSTACK_DEV_EXTRA_PLUGIN_PATHSnounsetJSON array of additional plugin module paths to co-load alongside the one under CHECKSTACK_DEV_PLUGIN_PATH. The dev script sets this automatically based on package.json dependencies.
CHECKSTACK_DEV_AUTHnofalseWhen true, registers a synthetic auth service that auto-grants every access rule. Strictly refused when NODE_ENV=production (the process throws at boot). Useful for testing plugins without going through a login flow.

CHECKSTACK_DEV_AUTH=true disables every access guard in the platform. Never set it on an exposed instance.

The satellite is a separate process. These variables apply to the satellite container only, not to the core backend.

VariableRequiredDefaultWhat it does
CHECKSTACK_CORE_URLyesnoneURL of the Checkstack core the satellite connects to. Reachable from wherever the satellite runs.
CHECKSTACK_SATELLITE_CLIENT_IDyesnoneStable id you assign in the Satellite registration UI. Identifies this satellite to the core.
CHECKSTACK_SATELLITE_TOKENyesnoneBearer token issued by the core when the satellite was registered. Treat as a credential.
DEBUGnounsetEnables verbose satellite logs.

The reference docker-compose.yml adds a few Postgres-side variables for convenience. They are read by the Postgres image, not by Checkstack itself.

VariableDefault in composeWhat it does
POSTGRES_USERcheckstackDB user the Postgres container creates on first boot. Plugged into DATABASE_URL.
POSTGRES_PASSWORDcheckstackPassword for the above user. Change this for any non-throwaway install.
POSTGRES_DBcheckstackDatabase name created on first boot.

A complete .env for a single-host production install looks like this:

# Core
BASE_URL=https://status.example.com
NODE_ENV=production
LOG_LEVEL=info
# Database
POSTGRES_USER=checkstack
POSTGRES_PASSWORD=replace-me
POSTGRES_DB=checkstack
# Auth
BETTER_AUTH_SECRET=replace-with-32-plus-char-random-string
# Encryption
ENCRYPTION_MASTER_KEY=replace-with-64-hex-chars

For multi-replica deployments, add:

INTERNAL_URL=http://checkstack-svc:3000