Self-hosting
Configuration reference
What does every environment variable do?
Every variable the three Vantage images read, taken from their source. On the Nomad deployment
the job templates set them, mostly from Vault; in compose, compose/env/vantage.env and the
vantage-analytics.env that vantage.sh provision writes.
| Image | Reads its config in | Listens |
|---|---|---|
vantage-web (analytics-web) | apps/web | PORT, default 4444 |
vantage-dataplane | services/dataplane | PORT, default 8081 |
vantage-cube | data/cube/cube.js, plus Cube's own CUBEJS_* | 4000 |
Required means the process refuses to start or the feature fails without it. Prod means
required only when NODE_ENV=production, which both Node images set. Defaults are for local
development; every secret default must be replaced outside a laptop.
analytics-web
Runtime and edition
| Variable | Meaning | Required | Default |
|---|---|---|---|
NODE_ENV | production turns on __Host- secure cookies and the production checks below | production in the image | |
PORT | HTTP port | 4444 | |
VANTAGE_EDITION | standalone (own signup, plans, billing) or norims (inside a Norims cluster); anything else fails start-up | norims | |
NORIMS_ENV | Environment segment prefixed to warehouse databases and users (preview_tenant_<slug>), Valkey keys and Vault tenant paths; empty for prod | empty | |
ALLOWED_HOSTS | Host allow-list for the Vite dev server only; the production server does not read it | all hosts | |
VANTAGE_CONTACT_EMAIL | Address the pricing page offers for Enterprise | empty |
Sign-in (Zitadel OIDC)
| Variable | Meaning | Required | Default |
|---|---|---|---|
OIDC_ISSUER | Zitadel issuer URL, https://auth.<domain> | yes | |
OIDC_CLIENT_ID | Client id of the PKCE user-agent app (no client secret) | yes | |
OIDC_REDIRECT_URI | https://analytics.<domain>/auth/callback | yes | |
OIDC_POST_LOGOUT_REDIRECT_URI | Where Zitadel returns after sign-out | / | |
OIDC_TENANT_CLAIM | Claim used as the workspace id | urn:zitadel:iam:user:resourceowner:id | |
OIDC_ROLES_CLAIM | Claim carrying project roles | urn:zitadel:iam:org:project:roles | |
SESSION_ENC_KEY | 32-byte base64url key encrypting server-held sessions | yes | |
SIGNUP_ENABLED | true serves /signup; signup stays off unless the next two are also set | off | |
ZITADEL_PROJECT_ID | Project each new organisation is granted | for signup | |
ZITADEL_SERVICE_ACCOUNT_KEY / ZITADEL_SERVICE_ACCOUNT_KEY_PATH | Machine-key JSON (inline, or a file path) of the vantage-sdk user that creates organisations | one, for signup | |
TRUSTED_PROXY_HOPS | Proxies that append to X-Forwarded-For; the client address used for signup and MCP rate limits | 0 (header ignored) |
Control plane, warehouse, semantic layer
| Variable | Meaning | Required | Default |
|---|---|---|---|
CONTROLPLANE_DATABASE_URL | Postgres URL the server connects with; must not be a superuser, or row security is bypassed | yes | postgres://app:app@localhost:5455/analytics |
CONTROLPLANE_ADMIN_URL | Owner connection for bootstrap-controlplane.sh (migrations, roles, policies) | CONTROLPLANE_DATABASE_URL | |
STARROCKS_FE_HOST | StarRocks frontend for SQL editor queries, port 9030 fixed | yes | localhost |
DBT_STARROCKS_HOST | Host written into BYO dbt profiles.yml | localhost | |
CUBE_API_URL | Cube REST base | yes | http://localhost:4000/cubejs-api/v1 |
CUBEJS_API_SECRET | Signs the per-workspace JWTs sent to Cube; same value as Cube's | yes | dev-cube-secret |
CUBE_SERVICE_TOKEN | Token Cube presents on /api/internal/cube/* | prod | dev-cube-secret |
VAULT_ADDR | Vault API | yes | http://localhost:8200 |
VAULT_TOKEN | Vault token; under Nomad the job's vault block sets it | yes | dev-vault-token |
REDIS_HOST, REDIS_PORT, REDIS_PASSWORD | Valkey for SQL budgets and MCP rate limits | localhost, 6379, change_me_in_production | |
REDIS_DISABLED | true skips Valkey: SQL budgets fail open, MCP limits count per process | false | |
TENANT_QUERY_BUDGET | SQL editor queries per workspace per rolling hour | 200 | |
SQL_TIMEOUT_MS | Longest a SQL editor query may run | 30000 | |
SQL_CREDS_TTL_MS | How long a workspace's read-only credential is cached | 300000 |
Ingest and service tokens
| Variable | Meaning | Required | Default |
|---|---|---|---|
DATAPLANE_URL | Dataplane base for server-to-server calls | yes | http://localhost:8081 |
PUBLIC_DATAPLANE_URL | Dataplane base the browser uploads to, https://uploads.<domain> | DATAPLANE_URL | |
UPLOAD_TOKEN_SECRET | Signs upload tickets; same value as the dataplane's | prod | dev-upload-secret |
INGEST_TOKEN | Token presented to the dataplane, and the only one accepted from it | prod | dev-ingest-web |
N8N_EDITOR_URL | n8n editor that platform sources link to; empty hides the link | empty | |
N8N_WEBHOOK_URL | n8n endpoint the Health page probes | http://localhost:5678/webhook/cdc-sync | |
BACKEND_URL | norims-backend platform API (Norims edition: pack registry, tenant settings) | Norims | http://localhost:3500 |
PLATFORM_TOKEN | Token for BACKEND_URL | when BACKEND_URL is not the default | dev-packs-web |
PROVISION_TOKENS_BACKEND | current[,previous] tokens accepted from norims-backend on provision and teardown routes | prod, Norims edition |
AI, digest, billing
| Variable | Meaning | Required | Default |
|---|---|---|---|
ANTHROPIC_API_KEY | Turns on every AI feature and /api/mcp; unset hides them | ||
ANTHROPIC_HAIKU_MODEL | Model for the light tier | claude-haiku-5-5 | |
ANTHROPIC_SONNET_MODEL | Model for the heavy tier | claude-sonnet-5-5 | |
RESEND_API_KEY, RESEND_FROM | Weekly digest mail; both needed, otherwise in-app only | ||
UNSUBSCRIBE_SECRET | Signs unsubscribe links (valid a year) | derived from SESSION_ENC_KEY | |
PUBLIC_APP_URL | Origin for links in mail and MCP results | origin of OIDC_REDIRECT_URI | |
DIGEST_BATCH | Most users one digest tick handles | 100 | |
DIGEST_TICK_BUDGET_MS | Time after which a tick starts no new user | 60000 | |
DODO_API_KEY | Dodo Payments key; unset, billing answers 503 billing_not_configured | standalone billing | |
DODO_ENVIRONMENT | test or live; anything else fails | test | |
DODO_WEBHOOK_SECRET | Verifies /api/billing/webhook/dodo | with DODO_API_KEY | empty |
DODO_BRAND_ID | Brand whose products count as Vantage plans | with DODO_API_KEY | empty |
dataplane
| Variable | Meaning | Required | Default |
|---|---|---|---|
NODE_ENV | production enforces the two checks marked prod | production in the image | |
PORT | HTTP port | 8081 | |
VANTAGE_EDITION | standalone makes scheduled syncs ask analytics-web whether the plan allows loads | not standalone | |
NORIMS_ENV | Environment prefix, as for analytics-web | empty | |
CONTROLPLANE_DATABASE_URL | Control-plane Postgres (sources, datasets, cursors, runs) | yes | postgres://app:app@localhost:5455/analytics |
CONTROLPLANE_URL | analytics-web base, for dataset-ready, loads-allowed and digest ticks | yes | http://localhost:4444 |
STARROCKS_FE_HOST | StarRocks frontend, port 9030 fixed | yes | |
STARROCKS_BE_HOST | Stream-load target, port 8040 | STARROCKS_FE_HOST | |
STARROCKS_USER, STARROCKS_PASSWORD | Admin user with DDL, DML and user administration (dataplane_svc) | yes | |
RUSTFS_ENDPOINT, RUSTFS_REGION, RUSTFS_ACCESS_KEY_ID, RUSTFS_SECRET_ACCESS_KEY | S3 staging store; the key is the bucket-scoped svc-dataplane account | yes | |
RUSTFS_PARQUET_STAGING_BUCKET | Staging bucket | yes | |
MAX_FILE_SIZE_BYTES | Largest upload | 536870912 (512 MiB) | |
UPLOAD_TOKEN_SECRET | Verifies upload tickets | prod | dev-upload-secret |
INGEST_TOKENS_<NAME> | current[,previous] tokens for caller <name>; at least one | prod | |
SCHEDULER_ENABLED | false runs no Temporal worker | true | |
TEMPORAL_ADDRESS | Temporal frontend | temporal:7233 | |
TEMPORAL_NAMESPACE | Namespace for the worker and schedules | analytics | |
TEMPORAL_TASK_QUEUE | Task queue | ingestion | |
TEMPORAL_TLS_CA_PATH, TEMPORAL_TLS_CERT_PATH, TEMPORAL_TLS_KEY_PATH | mTLS to Temporal; all three or none | none (plain) | |
N8N_WEBHOOK_URL | n8n webhook a scheduled sync calls | for scheduled syncs | http://n8n:5678/webhook/cdc-sync |
cube
Read by data/cube/cube.js inside the Cube container; setting them on analytics-web does
nothing.
| Variable | Meaning | Required | Default |
|---|---|---|---|
CUBEJS_API_SECRET | Verifies analytics-web's JWTs (HS256) | yes | |
CUBEJS_DEV_MODE | true skips JWT verification and defaults the workspace to test-tenant; must be false outside development | ||
CONTROLPLANE_INTERNAL_URL | analytics-web base for schema, schema version, workspace list and credentials | yes | http://localhost:4444 |
CUBE_SERVICE_TOKEN | Token presented to analytics-web | yes | dev-cube-secret |
CUBE_APP_ID_PREFIX | Prefix of the per-workspace app id | tenant_ | |
CUBEJS_DB_HOST, CUBEJS_DB_PORT, CUBEJS_DB_NAME | StarRocks frontend | yes | |
CUBEJS_DB_USER, CUBEJS_DB_PASS | Fallback SELECT-only user (cube_svc), used for a workspace with no ro_<slug> credential yet | yes |