Environment variables (single source)

Every supported env-var with default, scope, and the container that reads it — generated from env and docker-compose.yaml.

Purpose

This page is the single source of truth for GENIE.AI environment variables. It supersedes the three divergent tables that previously lived in deploy/install-guide.md, deploy/docker-compose-setup.md, and deploy/docker-swarm-setup.md (22 drift errors in Wave 1).

The defaults are pulled from the root env file and docker-compose.yaml. When a default disagrees with this table, fix the source first (the file in the repo), then regenerate.

Required secrets (no default — must be set)

VariableUsed byNotes
ARANGO_PASSWORDbackend, dataprep, retriever, document-repositoryRoot DB password. Must be URL-safe; avoid +, /, =
POSTGRES_PASSWORDpostgres (kong-db, keycloak-db)Kong + Keycloak shared PostgreSQL instance
KONG_DB_PASSWORDkong-db, kongDedicated Kong DB user
KEYCLOAK_DB_PASSWORDkeycloak-db, keycloakDedicated Keycloak DB user
KEYCLOAK_ADMIN_PASSWORDkeycloakMaster admin console password
KEYCLOAK_CLIENT_SECRETbackend (BFF)OIDC client secret for genie-app
KEYCLOAK_PROXY_CLIENT_SECRETbackend (admin proxy)Service account secret for Admin API proxy
KC_DATAPREP_CLIENT_SECRETdataprepclient_credentials grant secret
EMAIL_HOSTkeycloakSMTP server hostname
EMAIL_PORTkeycloakSMTP server port (default 587)
EMAIL_USERkeycloakSMTP username
EMAIL_PASSWORDkeycloakSMTP password
EMAIL_FROMkeycloakFrom address for user-verification emails
HUGGING_FACE_HUB_TOKENvllm, embedding, reranker (via HF_TOKEN)Required to pull models
VLLM_API_KEYall OPEA clientsBearer token sent as Authorization: Bearer
GRAFANA_ADMIN_PASSWORDgrafanaRequired when ENABLE_OBSERVABILITY=1
GENIE_ADMIN_PASSWORDbackend (BFF)Realm-level admin bootstrap password — created on first run if absent. See Keycloak Admin Guide

Keycloak realm & OIDC clients (defaults — override per deployment)

VariableDefaultUsed byNotes
KEYCLOAK_URLhttps://localhost/authbackend, frontend, mobilePublic URL users reach your Keycloak at. BFF validates tokens against <KEYCLOAK_URL>/realms/<KEYCLOAK_REALM>.
KEYCLOAK_REALMgeniebackend, frontend, mobileRealm name. Switch via Keycloak admin console dropdown.
KEYCLOAK_CLIENT_IDgenie-appbackend, frontendWeb SPA OIDC client id (must match the realm client).
KC_DATAPREP_CLIENT_IDdataprep-service-clientdataprepService-account client for the client_credentials grant.
KC_MOBILE_CLIENT_IDgenie-mobile-<institution>mobileMobile OIDC client id (PKCE flow). Per-flavor suffix — see mobile/genie_ai_mobile/lib/config/flavors/<flavor>.dart (e.g. genie-mobile-itu).
KC_MOBILE_REDIRECT_SCHEMEcom.<institution>.genieaimobileDeep-link scheme registered on Android/iOS for the OIDC redirect. Android package convention (com.<institution>.genieai[.<flavor>]).

Realm-level admin bootstrap (defaults — override per deployment)

VariableDefaultUsed byNotes
GENIE_ADMIN_USERNAMEgenie-adminbackend (BFF)Realm-level admin username; created on first run if absent.
GENIE_ADMIN_EMAIL(unset)backend (BFF)Email for the bootstrap admin user; recommended for emailVerified: true on first login.
TRANSLATION_CACHE_PASSWORD(random per-service, persisted in volume)backend (BFF)Password for the translation-cache Redis user (set when a Redis password is enabled).

Deployment-specific

VariableDefaultUsed byNotes
VLLM_TRANSLATION_MODEL_IDgoogle/gemma-3-4b-ittranslatione.g. facebook/m2m100-418M
EMBEDDING_MODEL_IDBAAI/bge-large-en-v1.5embeddingAny TEI-supported encoder
RERANKER_MODEL_IDBAAI/bge-reranker-v2-m3rerankerAny TEI-supported cross-encoder
VLLM_LLM_MODEL_IDmeta-llama/Meta-Llama-3.1-8B-InstructvllmMust support guided JSON (response_format={"type":"json_object"})
MODEL_LLM_TIMEOUT_SECONDS180dataprep, retrievervLLM chat completions. Read by core/model_http_policy.py. On every shipped topology it is parsed but unused: its only consumer is the retriever’s OpenAI-key probe, and no service is given OPENAI_API_KEY.
MODEL_LLM_MAX_RETRIES2dataprep, retrieverSDK retries on 408/409/429/5xx and connection errors. 0 is honoured as a real value. Values above 10 are rejected.
MODEL_SUMMARIZER_TIMEOUT_SECONDS600retrieverDocument summarizer. A NEW ceiling, not the openai default kept. Not lowered: the call has no fallback, so its timeout becomes a 500 on the chat request.
MODEL_EMBEDDING_TIMEOUT_SECONDS600retrieverEmbedding client, OpenAI-API branch ONLY. Also a NEW ceiling — langchain-openai forwards request_timeout (default None), which overrides the SDK default. Lowering it yields a silently EMPTY retrieval: the except clause returns [] ahead of the BM25 leg.
MODEL_RERANK_TIMEOUT_SECONDS300rerankerTEI rerank. Not lowered for the same reason as the summarizer.
MODEL_AUTH_TIMEOUT_SECONDS300dataprepKeycloak service-account token fetch. Separate from the control-plane budget because every ingestion-log write and status update waits on it, one attempt, no retry, re-raises on failure.
MODEL_CONTROL_PLANE_TIMEOUT_SECONDS30dataprep, chatqnaIngestion-log writes, doc-status updates, doc-repo callbacks. Not the Keycloak token fetch.
MODEL_CONNECT_TIMEOUT_SECONDS30dataprep, rerankerThe CONNECT phase ceiling for every aiohttp session this policy budgeted. aiohttp’s default session already carried 30 s; passing an explicit ClientTimeout(total=...) drops it, and None means no limit rather than “inherit”. Raise for slow DNS or a routed mesh.
MODEL_PROBE_TIMEOUT_SECONDS10dataprep, retriever, chatqnaThe /v1/models probe behind the TTL-cached model-id lookup. Degrades to the configured model id. Raise it on a remote GPU node whose models load slowly — the fallback otherwise picks the configured id instead of the served one.
RERANKING_STRATEGYslicechatqnaslice / threshold / slice_threshold / knee_threshold / adaptive
RERANKER_TOP_N3chatqnaTop chunks kept by slice/slice_threshold
CONTEXTUAL_RETRIEVAL_ENABLEDtruedataprepOn by default; prepends doc-context prefix
DATAPREP_CONTEXTUAL_MODEL(empty = reuse VLLM_LLM_MODEL_ID)dataprepMust support guided JSON
DATAPREP_CONTEXTUAL_DOC_BUDGET100000 (Python code) / 6000 (compose override)dataprepMax chars fed to context LLM (~1500 tokens; ≤0 disables truncation). Compose override — docker-compose.yaml sets the per-chunk default to 6000 (the doc-level sibling _DOC_LEVEL stays at 100000); the compose file wins at runtime. To use the full Python default, set DATAPREP_CONTEXTUAL_DOC_BUDGET=100000 in .env before docker compose --env-file .env up -d (or env.t4 / env.rtx6000 overlays per Step 6d).
DATAPREP_CONTEXTUAL_MAX_TOKENS512dataprepPer-call max output tokens for context generation
CONTEXTUAL_STRATEGYper_chunkdataprepper_chunk (Anthropic recipe — default) or doc_level (N× cheaper, same context for every chunk)
CONTEXTUAL_LABEL_RAWtruedatapreptrue = label raw chunk, use context only for embedding
CORS_ALLOWED_ORIGINShttp://localhost:3000,http://localhost:8090,http://127.0.0.1:8090,https://${NGINX_PUBLIC_DOMAIN:-localhost}backendComma-separated origins; localhost dev default
CSP_CONNECT_SRC'self' http://localhost:3000 http://localhost:8090 http://127.0.0.1:8090 ws://localhost:3000 ws://localhost:8090nginxContent-Security-Policy connect-src; localhost dev default
NGINX_PUBLIC_DOMAINlocalhostnginxPublic domain
VUE_APP_API_URL/apifrontendFrontend API base
VUE_APP_AVAILABLE_LOCALES(unset = all)frontendComma-separated codes (e.g. en,es) — see Restrict active locales
KEYCLOAK_SUPPORTED_LOCALES(curated default)keycloakJSON array (e.g. ["en","es"]) — see Restrict active locales
STREAMING_TRANSLATION_ENABLED0chatqna1/0; stream translated tokens during generation
KC_GRAFANA_CLIENT_IDgrafanakeycloak, grafanaOIDC client ID for Grafana SSO
KC_GRAFANA_CLIENT_SECRET(required when observability enabled)keycloak, grafanaOIDC client secret

Observability

VariableDefaultUsed byNotes
ENABLE_OBSERVABILITY0root0/1 (not true/false)
GRAFANA_ADMIN_USERadmingrafana
GRAFANA_PORT3002grafanaHost port; avoids Backend port conflict
VICTORIAMETRICS_RETENTION30dvictoriametrics
VICTORIALOGS_RETENTION30dvictorialogs
VICTORIALOGS_URL(no in-code default — VictoriaLogsClient constructor must receive baseURL; Ansible env.j2:243 sets http://victorialogs:9428)backendVL HTTP base URL. Injected by env.j2; bypass only when running outside Ansible and set it explicitly.
VICTORIALOGS_TENANT_ID(no in-code default — read by shared/lib/melt/victorialogs-client.js:105, defaults AccountID:0, ProjectID:0 when unset)backendTenant header for /select/logsql/* (AccountID:ProjectID). Ansible splits VICTORIALOGS_TENANT_ID into VICTORIALOGS_TENANT_ID_ACCOUNT_ID + VICTORIALOGS_TENANT_ID_PROJECT_ID for the underlying VL request.
VICTORIATRACES_RETENTION30dvictoriatraces
MELT_PROVIDERvictorialogs (hardcoded constant in components/shared/lib/melt/index.js)backendFuture-proof seam selector for the OTel metrics/logs/traces exporter. Whitelisted by tests/config-validator/ so a deployer may override the env file; the runtime constant is the actual current value. Today there is only one backend implementation.
OTEL_TRACES_SAMPLER_RATE100.0backend, opea0.0–100.0
KONG_TRACING_INSTRUMENTATIONSrequestkong
KONG_TRACING_SAMPLING_RATE1.0kong0.0–1.0
OTEL_EXPORTER_OTLP_ENDPOINThttp://otel-collector:4318backend, opea, kongBase URL for OTLP
OTEL_EXPORTER_OTLP_LOGS_ENDPOINT(not set — collector derives /v1/logs from OTEL_EXPORTER_OTLP_ENDPOINT)backend, opeaSet only when the logs endpoint must override the inferred one (signal-specific URL is used as-is; no path appended).
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT(not set — collector derives /v1/traces from OTEL_EXPORTER_OTLP_ENDPOINT)backend, opeaSet only when the traces endpoint must override the inferred one.
VL_QUERY_TIMEOUT_MS30000backendaxios timeout for VictoriaLogs query / hits

Prompts (override defaults)

VariableDefaultUsed byNotes
CHATQNA_SYSTEM_PROMPT(built-in)chatqnaLLM system prompt
CHATQNA_ABSTENTION_INSTRUCTIONS(built-in)chatqna
CHATQNA_ENFORCE_ABSTENTIONtruechatqna
LABEL_SELECTOR_SYSTEM_PROMPT(built-in)dataprep{labels_list} placeholder
CONTEXTUAL_RETRIEVAL_PROMPT(built-in)dataprep{document_context} placeholder

Service ports (with defaults baked in)

See Configure → CORS / CSP / public-domain for the nginx / kong / keycloak port map.

Variables with code-side defaults (not in env)

Ports, database URLs, and service configurations default in docker-compose.yaml / code, not in env. The full list is too long to reproduce here — see docker-compose.yaml for the canonical values.

GPU profile overlays

env.t4 and env.rtx6000 overlay these on top of env to set GPU-memory utilization and model-length limits per profile. They are read via docker compose --env-file .env --env-file env.<profile> up -d.

Variableenv.t4 defaultenv.rtx6000 defaultNotes
VLLM_GPU_UTILIZATION0.40.6Fraction of GPU memory vLLM pre-allocates
VLLM_MAX_MODEL_LEN20484096Context length
VLLM_MAX_NUM_SEQS641024Max concurrent sequences
VLLM_DTYPEhalf(unset, defaults in docker-compose)Compute dtype
VLLM_TRANSLATION_GPU_UTILIZATION0.30.4
VLLM_TRANSLATION_MAX_MODEL_LEN20488192
VLLM_TRANSLATION_MAX_NUM_SEQS1632

Validation

cd tests/config-validator
npm install
npm test

The validator fails CI if a required env-var is undocumented here.