Configuration
Every setting that controls Orbtrace's behaviour — environment variables, the AI provider, authentication, licensing, retention, sampling — grounded in the actual .env.example. Read before any real-traffic deployment.
Orbtrace's defaults are fine for the quickstart. Before you put it in front of production traffic, walk through this page once and set each value deliberately. Every variable here is real — it matches the shipped docker/.env.example.
Where settings live
- .env fileEnvironment variables read at container startup: database connection, the AI provider key, your license, public URLs. Changing one needs a container restart.
- Admin UIThings you change while running: alert rules, SLOs, dashboards, the active AI provider/model, per-service sampling caps, retention windows, user roles, integrations. Stored in PostgreSQL; live immediately.
- docker-compose.yml / values.yamlTopology — how many Doris nodes, resource limits, exposed ports, the Doris profile. Edit when you outgrow the default sizing.
The naming convention
A third-party SDK or external system reads it directly → vendor-native name, no prefix (ANTHROPIC_API_KEY, PGHOST, DORIS_USER, REDIS_HOST). Only Orbtrace's own code reads it → ORBTRACE_ prefix (ORBTRACE_SECRET_KEK, ORBTRACE_AI_PROVIDER). This is why, for example, the Doris connection vars are bare DORIS_* (the Collector reads them too) but the HikariCP pool sizing is ORBTRACE_DORIS_POOL_* (only Orbtrace reads it).
Core
| Variable | Default | What it does |
|---|---|---|
ORBTRACE_DEPLOYMENT_ENV | prod | A tag attached to Orbtrace's own self-telemetry — handy when one Doris receives signals from several Orbtrace deploys. |
ORBTRACE_HTTP_PORT | 8080 | The host port the UI + REST API are published on (compose path; the container always listens on 8080). The two URL variables below default to http://localhost:<this port> and follow it automatically — set them explicitly only behind a proxy or a real domain. Available from bundle 2.0.8. |
ORBTRACE_FRONTEND_URL | http://localhost:8080 | The public URL users hit. Used to build the OIDC redirect URIs your IdP returns to — must match what you registered. Set to your real host behind a proxy. |
ORBTRACE_BACKEND_URL | http://localhost:8080 | The URL embedded in issued sign-in tokens (the token issuer). Same as the frontend on a single-host deploy. |
PostgreSQL (settings database)
libpq-native names — Spring reads bare ${PGHOST} etc.
| Variable | Default | What it does |
|---|---|---|
PGHOST | postgres | Service hostname (set in compose). |
PGPORT | 5432 | Port. |
PGDATABASE | orbtrace | Database name. |
PGUSER | orbtrace | User. |
PGPASSWORD | change-me-locally — change it | Password. |
Apache Doris (telemetry database)
Doris-native names — the Collector reads the same ${DORIS_USER} / ${DORIS_PASSWORD} from otelcol-config.yaml.
| Variable | Default | What it does |
|---|---|---|
DORIS_FE_HOST | doris-fe | Frontend hostname (set in compose). |
DORIS_FE_QUERY_PORT | 9030 | MySQL-protocol port used for SELECT queries. |
DORIS_FE_HTTP_PORT | 8030 | HTTP port (Stream Load / management). |
DORIS_USER | root | User. |
DORIS_PASSWORD | empty — set it | Password. The default Doris FE ships with no password; set one and pass it to your Collector too. |
DORIS_DB | orbtrace | Database name. |
ORBTRACE_DORIS_MIGRATION_MODE | apply | apply (Orbtrace creates/updates the Doris schema at startup and blocks readiness until done — the standard path), validate (schema applied out-of-band by a DBA; Orbtrace only verifies on boot), or disabled (skip — dev only). |
ORBTRACE_DORIS_POOL_* | sensible | HikariCP pool sizing for Doris reads (e.g. ORBTRACE_DORIS_POOL_MAXIMUM_SIZE). Raise for many concurrent users. Orbtrace never writes to Doris — that's the Collector's job. |
Valkey (cache)
| Variable | Default | What it does |
|---|---|---|
REDIS_HOST | valkey | Hostname (set in compose). |
REDIS_PORT | 6379 | Port. |
REDIS_PASSWORD | empty | Set if your Valkey requires AUTH. |
License
| Variable | Default | What it does |
|---|---|---|
ORBTRACE_LICENSE_KEY | empty | Paste your signed .orblic token contents here, or leave blank to run the free COMMUNITY edition. You can also mount /etc/orbtrace/license.orblic or upload via Admin → License. Full details in Licensing. |
AI provider (Causal RCA + Astra + Replay)
ORBTRACE_AI_PROVIDER selects which LLM the AI features use — one active provider at a time for citation consistency. Valid values: anthropic (default), openai, azure-openai, google-gemini, ollama, openai-compatible. Set the matching credentials; leave the others empty. Air-gapped deployments use ollama or a self-hosted openai-compatible server. You can switch the active provider and model — and store keys, endpoints, and TLS — at runtime in Admin → AI.
| Provider | Required variables |
|---|---|
anthropic | ANTHROPIC_API_KEY. Optional: ANTHROPIC_BASE_URL. |
openai | OPENAI_API_KEY. Optional: OPENAI_BASE_URL. |
azure-openai | AZURE_OPENAI_API_KEY, AZURE_OPENAI_ENDPOINT, AZURE_OPENAI_DEPLOYMENT. |
google-gemini | GOOGLE_GENAI_API_KEY (or GOOGLE_GENAI_PROJECT_ID + GOOGLE_GENAI_LOCATION for Vertex AI). |
ollama | OLLAMA_BASE_URL (e.g. http://host.docker.internal:11434). Model chosen in the UI. |
openai-compatible | ORBTRACE_AI_OPENAI_COMPATIBLE_BASE_URL (e.g. a vLLM / TGI / LocalAI / LM Studio server). Optional: ORBTRACE_AI_OPENAI_COMPATIBLE_API_KEY. Base URL + TLS are usually set in Admin → AI. |
Env vs stored — what needs a restart. Every value above is the bootstrap and fallback. From Admin → AI you can also store an API key (encrypted at rest) and, for the on-prem providers (ollama, openai-compatible), a base URL + TLS trust — a stored value overrides the env var and takes effect immediately, no restart. Changing an env key or base URL still needs a container restart. To encrypt stored keys at rest, set ORBTRACE_SECRET_KEK to a base64 of 16/24/32 random bytes (same operator-owned-secret model as ORBTRACE_JWT_KEK); when unset, keys are stored in plaintext and a warning is logged. Stored keys are never returned by the API — the admin screen shows only a "stored" flag and the last 4 characters.
The AI orchestration knobs (all ORBTRACE_AI_* / ORBTRACE_ASTRA_*, all optional with baked-in defaults) cover budgets, failover, response caching, and the Astra assistant's per-tool limits — e.g. ORBTRACE_AI_BUDGET_ENABLED, ORBTRACE_AI_FAILOVER_ENABLED, ORBTRACE_ASTRA_BUDGET_RESET_INTERVAL. See the "Behavioral tuning knobs" block in .env.example for the full list. Note: vendor credentials use vendor-native names; ORBTRACE_AI_* is only for Orbtrace's own orchestration.
Authentication
Orbtrace signs users in through an identity provider (SSO). Set credentials for at least one of the four paths and restart. Full per-provider walkthrough in Authentication.
| Provider | Variables |
|---|---|
GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET | |
| Microsoft Entra | MICROSOFT_CLIENT_ID, MICROSOFT_CLIENT_SECRET, MICROSOFT_TENANT |
| GitHub | GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET |
| Custom OIDC (Keycloak, Authelia, Auth0, Okta, …) | OIDC_CLIENT_ID, OIDC_CLIENT_SECRET, OIDC_ISSUER_URI, ORBTRACE_OIDC_DISPLAY_NAME |
A client-id left at the literal change-me is stripped at startup, so the button simply doesn't appear — there's no separate "enable" flag and no broken button.
| Variable | Default | What it does |
|---|---|---|
ORBTRACE_BOOTSTRAP_ADMIN_USERNAME | empty | The email pinned as the deployment admin — provisioned (or promoted on next login) to role ADMIN. Case-insensitive; re-applied every login. Leave blank to bootstrap admin via SQL. |
ORBTRACE_BOOTSTRAP_ADMIN_PASSWORD | empty | Optional, evaluation only. Set it alongside the username to also get a local username/password login form (no IdP needed). Hashed in memory, never persisted; a password without a username aborts startup. No MFA/lockout — leave blank in production. |
ORBTRACE_OIDC_DISPLAY_NAME | Single Sign-On | Label on the generic OIDC sign-in button. |
The redirect URI to register in your IdP is {ORBTRACE_BACKEND_URL}/login/oauth2/code/{provider} where {provider} is google, microsoft, github, or oidc.
Retention
Two different mechanisms — don't confuse them:
- Telemetry retention (how long logs / traces / metrics stay in Doris) is not an env var. It's set by the Doris profile (
small/medium/large, selected viadoris.profile.activeProfilein Helm or the profile baked into the Compose image) — e.g. thesmallprofile keeps 7 days of logs, 14 of traces, 30 of metrics. Doris drops whole partitions when they age out, so disk is reclaimed immediately. To change telemetry retention you change the profile (or overridedoris.profile.retention.*, which is in days), not an env var. - Operational retention (audit log + Replay/timeline history) is tunable, and also editable live in Admin → Retention:
| Variable | Default | What it does |
|---|---|---|
ORBTRACE_AUDIT_RETENTION_ENABLED | false | Off by default (SOC2 wants 12 months). When on, prunes audit_events older than the max-age. |
ORBTRACE_AUDIT_RETENTION_CRON | 0 0 3 * * * | When the nightly audit sweep runs (Spring 6-field cron, UTC). |
ORBTRACE_REPLAY_RETENTION_CRON | 0 0 3 * * * | When the Replay/timeline sweep runs. |
Sampling
Sampling is not a single on/off env var. It's two cooperating layers:
- Your Collector's
tail_samplingprocessor makes the keep/drop decision and enforces the hard-keep rules — errors, traces slower than p99, novel paths, SLO violations, and anomaly-tagged traces are always kept. These live in your Collector config (otelcol-config.yaml), not in Orbtrace. - Orbtrace publishes the probabilistic floor: per-service monthly trace-count caps you set in Admin → Sampling. Orbtrace computes burn-rate against the cap and republishes
/api/sampling/policy.yaml, which your Collector consumes. This defends Doris disk and keeps signal-to-noise high.
The one related env knob is ORBTRACE_SAMPLING_SLOW_TRACE_THRESHOLD_MS (default 1000) — the latency above which a trace counts as "slow" for hard-keep.
SLO recommendations
Orbtrace can suggest a per-service SLO target from each service's own latency history — it never sets one automatically. A nightly job derives the suggestion from the daily p95 a service stays under across the lookback window; an admin then reviews and Accepts it on the SLOs screen (and can trigger a recompute on demand there). See SLOs & alerting for the workflow.
Off by default. The two sample gates are a signal-quality bar: a service needs at least min usable days calendar days, each with at least min daily samples inbound-request spans, inside the lookback — otherwise no suggestion is produced, because there's too little history to set a target honestly. The defaults suit a production fleet; a brand-new install or a short demo has only a few hours of data on a single day, so a recompute returns nothing until you lower them (the dev profile already does, dropping them to 1 / 5).
| Variable | Default | What it does |
|---|---|---|
ORBTRACE_SLO_RECOMMENDATION_ENABLED | false | Master switch for the nightly suggestion job. Editable live. |
ORBTRACE_SLO_RECOMMENDATION_WINDOW_DAYS | 30 | Rolling lookback (days) the suggestion is derived from. Takes effect on restart. |
ORBTRACE_SLO_RECOMMENDATION_MIN_USABLE_DAYS | 7 | How many qualifying days a service needs before it's suggested a target. Lower it for a fresh or low-volume deployment. |
ORBTRACE_SLO_RECOMMENDATION_MIN_DAILY_SAMPLES | 50 | A day below this many inbound-request spans is too thin to count toward the above. |
CORS / proxy
| Variable | Default | What it does |
|---|---|---|
ORBTRACE_CORS_DISABLED | false | Set true only if a reverse proxy in front already handles CORS. |
ORBTRACE_CORS_ORIGIN_PATTERNS | derived | Override the allowed browser origins if the SPA is served from a different host than the API. |
Advanced behavioral knobs
Dozens of fine-grained timings and caps are overridable without a rebuild — async-stitching score weights, anomaly-trainer thresholds, alerting evaluation windows, Doris query/rollup caps, log-tail poll cadence, the operations percentile floors, and the Astra assistant's limits. Every one ships with a working default, so leave them unset unless you're tuning. Durations are ISO-8601 (PT30S, PT15M, P7D); crons are Spring 6-field. The complete, annotated list is the "Behavioral tuning knobs" block at the bottom of docker/.env.example.
A minimal production .env
ORBTRACE_FRONTEND_URL=https://orbtrace.example.com
ORBTRACE_BACKEND_URL=https://orbtrace.example.com
PGPASSWORD=<strong>
DORIS_PASSWORD=<strong>
# Optional license (blank → COMMUNITY edition)
ORBTRACE_LICENSE_KEY=
ORBTRACE_AI_PROVIDER=anthropic
ANTHROPIC_API_KEY=sk-ant-...
# Pin the first administrator (the email that gets ADMIN on first SSO login)
ORBTRACE_BOOTSTRAP_ADMIN_USERNAME=you@example.com
# Corporate SSO via Keycloak (or Auth0 / Okta / Authelia / Entra OIDC)
OIDC_CLIENT_ID=orbtrace
OIDC_CLIENT_SECRET=<from-your-IdP>
OIDC_ISSUER_URI=https://sso.example.com/realms/eng
ORBTRACE_OIDC_DISPLAY_NAME=Acme SSORestart vs. live
- Anything in
.env→ needsdocker compose up -d(orkubectl rollout restart) to take effect. - Anything in the Admin UI (alert rules, SLOs, sampling caps, retention windows, the active AI provider, user roles) → live immediately, no restart.
JWT signing keys are app-managed RSA — generated at first boot and stored in PostgreSQL, so there is no signing-secret env var to set or rotate. Rotating the key via POST /api/admin/jwt-keys/rotate invalidates every existing session token — everyone signs in again. That rotation is the one change with a user-visible blast radius. If policy requires operator-supplied keys, pin your own pair via ORBTRACE_JWT_PRIVATE_KEY / ORBTRACE_JWT_PUBLIC_KEY.