Authenticate to the registry, edit the chart values, run helm install, and verify — the step-by-step Helm install for Orbtrace once your datastores are ready.
With your datastores in place — Postgres/Valkey and Doris — install the stateless app with the OCI Helm chart.
Using OpenShift / OKD? Follow the OpenShift page, not this one
This page is the plain-Kubernetes flow; a plain helm install fails on OpenShift. The OpenShift page is self-contained — it walks the whole install end to end (node settings, Doris, registry, values, the overlay install, sign-in). You don't need this page there.
1
Prerequisites
A Kubernetes cluster and Helm 3.8+ (for OCI charts). Verify a default StorageClass with SSD-backed volumes exists — without one, the bundled Postgres/Valkey PVCs hang Pending forever:
kubectl get storageclass # one must be marked (default)
Stand up Doris first. The chart never deploys Doris, and the Orbtrace pod stays un-Ready until it can reach one. Follow Setting up Doris before installing, and note its FQDN for doris.host.
2
Authenticate to the registry
The chart and the image are private GHCR packages. Log in with the per-customer token Nivorbit gives you, then create an imagePullSecret the chart will use. <token> and <username> appear more than once below — replace every occurrence before running:
helm registry login authenticates the Helm CLI to pull the chart; the Secret + global.imagePullSecrets (next step) let the runtime pods pull the image. Air-gapped? Mirror the GHCR images and the OCI chart into your internal registry and point global.imageRegistry at it — see Air-gapped operation.
3
Get the chart and write your overrides
Pull and unpack the chart so you have the sizing presets and the OpenShift overlay locally (helm show values only prints the default values.yaml — it can't hand you the values-small/medium/large.yaml or values-openshift.yaml files, which is why you unpack):
You don't copy the whole values.yaml. When you install ./orbtrace, Helm already applies the chart's own values.yaml as the base — you just write a small my-values.yaml with the handful of keys you change, layered on top (step 4). Create it next to the unpacked orbtrace/ directory with at least:
my-values.yaml
global: imagePullSecrets: [{ name: ghcr }] # the secret from step 2orbtrace: # JWT signing needs no value here — the app manages its RSA keys itself. ingress: hosts: [demo.orbtrace.com] # your external hostname(s); set orbtrace.ingress.tls for HTTPS # The app's OAuth2 URLs auto-derive from this host — no separate # frontendUrl/backendUrl needed on the ingress path. # On OPENSHIFT skip this block entirely: the overlay replaces the # Ingress with a Route — set openshift.route.host instead (a custom # host auto-derives the OAuth2 URLs too; see the OpenShift page). # Sign-in works out of the box: a break-glass local admin is provisioned # with a generated password (read it from the <release>-bootstrap-admin # Secret; a new password is required on first login). Wire SSO via # orbtrace.oidc.* for production. See "Signing in" below.# Doris — with the reference operator DorisCluster the defaults already# match, so most installs need NO doris.* keys here. Uncomment only what# differs on your side (see Setting up Doris):# doris:# host: <your-doris-fe-host> # a VM / managed FE, or non-default operator names# password: <doris-root-password> # only if your Doris has a root password — a fresh one has none# # Single-BE Doris (evaluation)? Also uncomment BOTH lines below, or the# # app aborts at boot ("replication num … available backend num is 1").# # Never in production — see Replication factor on the Setting up Doris page.# allowSingleReplica: true# profile: { replicationNum: 1 }postgres: password: <postgres-password> # required — chart refuses to install if empty; bundled Postgres, or set postgres.* for an external one
Other keys you may add: orbtrace.licenseKey (blank = free COMMUNITY — Licensing), orbtrace.oidc.* (your SSO providers), orbtrace.ai.* (AI provider for RCA/Replay), doris.profile.activeProfile (small / medium / large). Every available key and its default is in the unpacked orbtrace/values.yaml for reference — copy only the ones you override into my-values.yaml, so an upgrade never freezes you on an old default.
4
Install
Run this in the directory where you unpacked the chart (step 3) — ./orbtrace and the -f paths are relative to it. You layer (in order) your sizing preset, then your overrides; later -f files win, so your my-values.yaml overrides the preset:
On OpenShift this command is different (the values-openshift.yaml overlay is layered as the last -f) — use the one on the OpenShift page instead.
5
Wait for pods
kubectl -n orbtrace get pods -w
All pods should reach Running and pass readiness within ~3 minutes. The Orbtrace pod stays un-Ready until it can reach Doris (it applies the schema before binding) — so make sure your external Doris is up first. Confirm success in the app log:
kubectl -n orbtrace logs -f deploy/orbtrace-app -c orbtrace# ready when you see: [doris-migration] complete
A pod stuck un-Ready is almost always an unreachable Doris (or Postgres), or a replication factor your BE count can't meet (the app creates tables at doris.profile.replicationNum, default 2, which needs ≥2 live BE) — re-check the host/password and the replication factor against Setting up Doris.
6
Point DNS at the ingress
Add a DNS record from your hostname to the Ingress (or LoadBalancer) address the chart surfaces. Continue to First login.
Signing in — the break-glass admin (and your external URL)
Your first login. The chart provisions a break-glass local admin with a generated, per-install password (never a shared default — that would be a critical vulnerability). Read it, sign in as admin@orbtrace.local, and you'll be required to set a new password before a session is issued:
Wire SSO for production (orbtrace.oidc.* — Authentication); keep the local admin as break-glass or disable it with orbtrace.bootstrapAdmin.enabled=false.
Your external URL. OAuth2 redirects the browser to the app's public URL. The chart derives it from your orbtrace.ingress.hosts (or openshift.route.host) automatically — so the ingress path just works. If the browser instead lands on localhost:8080/oauth2/authorize ("This site can't be reached"), the URL didn't resolve (typically an auto-generated OpenShift Route host) — set orbtrace.frontendUrl + orbtrace.backendUrl to your public URL. Step-by-step recovery commands are on the OpenShift page.
One namespace per tenant
Orbtrace has no built-in multi-tenancy. To give two teams their own isolated instances, run two Helm releases in two namespaces. Each release is fully independent.