Skip to main content
Use these environment variables when you need to change how a self-hosted Stackdome hub connects to PostgreSQL, protects stored credentials, publishes its external URL, or integrates with GitHub. If you used the single-server installer, it already generated and wired the required values — see Install.

How values are read

Each variable is read once at startup. When a variable is unset, the server falls back to the default listed below; where no default is listed, the value stays empty.
A value the server cannot parse is discarded. What happens next depends on whether the variable has a default. With a default, you silently get the default: DB_MAX_CONNECTIONS=abc gives you 50 and DB_DEBUG_MODE=yes gives you false, with no warning either time. Without a default, the value stays empty and startup validation rejects it — DB_PORT=not-a-number exits with port is required. Double-check spelling when a setting appears to have no effect.

Values validated at startup

The server validates its configuration before it serves traffic and refuses to start on the first problem it finds, reporting it as <field> is required. It checks, in order:
  • bind_address, from SERVER_BIND_ADDRESS
  • the database — SSL mode, max connections, host, port, name, username, password, and the root certificate when SSL mode is require
  • jwt secret, from JWT_SECRET
  • log level, from LOG_LEVEL
  • encryption key, from ENCRYPTION_KEY, which must also be 64–1024 characters
The database dialect is validated too, but it is fixed to postgres in code and has no environment variable, so it never fails in practice.

Database

The API server stores all of its state in PostgreSQL.

Security

ENCRYPTION_KEY is the master key for AES-256-GCM encryption, with a per-value key derived from it via PBKDF2. It protects:
  • stack and resource secrets, and the environment-variable values you set on a resource
  • the credentials of every cluster you have registered — both the service-account token and the cluster CA data
  • registry credential passwords
  • git integration credentials
Changing ENCRYPTION_KEY after any data exists makes every previously encrypted value unreadable. The key is not stored alongside the ciphertext, and there is no re-key path — the server will fail to decrypt your existing stack secrets, registry credentials, and git integration credentials, and it will no longer be able to reach any registered cluster, because the stored token and CA data cannot be decrypted. Treat this value as permanent for the life of the installation, and back it up.
Rotating JWT_SECRET is safe by comparison: it only invalidates tokens that are already issued, so everyone is signed out and has to sign in again.

Server

Logging

GitHub

GITHUB_CLIENT_ID and GITHUB_CLIENT_SECRET come from a GitHub OAuth app and enable “sign in with GitHub”. GitHub sign-in is off until both the client ID and the client secret are set. Only then does the server register the /api/v1/auth/github routes, and only then does the web UI show the “Continue with GitHub” button — the UI reads that state from GET /api/v1/config, so setting one of the two without the other leaves sign-in exactly as it was.

Setting the redirect URI

GITHUB_REDIRECT_URI must equal your frontend origin plus /auth/github/callback, and it must match the Authorization callback URL registered on the GitHub OAuth app exactly. GitHub rejects the sign-in attempt if the two differ. Set either SERVER_EXTERNAL_URL so the server can derive this value, or set GITHUB_REDIRECT_URI explicitly. Without either value, the GitHub browser flow has no redirect URI.

Platform-wide GitHub App

These variables configure one GitHub App that organizations install for repository access and webhooks. If they are not all set, the platform-wide app is treated as unconfigured and organizations use the per-organization manifest flow instead.

Platform cluster

These variables bootstrap an infrastructure-only platform organization, its compute cluster, wildcard domain, TLS resources, and the default image-registry settings for organizations created on the platform. This is separate from the single-server installer’s Default organization and local cluster, which the installer creates through the API. The server validates this group as a unit at startup and refuses to boot on a partial configuration:
  • the three PLATFORM_CLUSTER_* variables must all be set, or all be unset
  • PLATFORM_CLUSTER_* and PLATFORM_BASE_DOMAIN must be set together — one without the other is an error
  • PLATFORM_EMAIL is required once a platform cluster is configured
  • PLATFORM_DNS_CLOUDFLARE_API_TOKEN is required once a platform cluster is configured
  • PLATFORM_ACME_ENVIRONMENT must be production or staging
  • PLATFORM_TLS_NAMESPACE cannot be empty once a platform cluster is configured
The Cloudflare token is written to a Secret named cloudflare-api-token in PLATFORM_TLS_NAMESPACE. Give it only the DNS permissions required for the platform domain and protect it as a production credential.

Runtime environment

Values are case-sensitive. Anything other than DEVELOPMENT or PRODUCTION makes the server panic at startup with env: <value> not defined before configuration validation.

What the installer already set

The installer generates these secret values on first run, keeps them in a Kubernetes Secret named stackdome-bootstrap-secrets in the stackdome-control-plane namespace, and reuses them on later installs and upgrades:
  • DB_PASSWORD — a random 24-character alphanumeric password
  • JWT_SECRET — 48 random bytes, base64-encoded
  • ENCRYPTION_KEY — 32 random bytes, hex-encoded, which is the 64 characters the validator requires
  • the generated admin password, plus the admin email and domain needed by installer bootstrap
  • any GitHub OAuth or platform GitHub App values supplied with installer flags
It sets DB_HOST, DB_PORT, DB_NAME, DB_USERNAME, LOG_LEVEL=info, STACKDOME_ENV=PRODUCTION, and SERVER_EXTERNAL_URL for the PostgreSQL instance and public URL it deployed. GitHub environment variables are added only when their installer flags were supplied. The single-server installer does not set the PLATFORM_* bootstrap group. To change a value afterwards, edit the environment variables on the api-server resource and let it redeploy. Read the warning about ENCRYPTION_KEY before you touch that one.