Deploying on Kubernetes
Run the stateless Orbtrace app in Kubernetes with the OCI Helm chart, and connect it to the datastores it needs. Overview, recommended architecture, and the step-by-step sub-pages.
One helm install runs the stateless Orbtrace server (replicas + HPA) plus optional backup CronJobs, and bundles two of the three datastores it needs by default — Postgres and Valkey — inside the cluster (either can instead point at a VM or managed service). The telemetry store (Doris) and the Collector are the two pieces you always run yourself; the chart only connects to them.
Deployed by the Helm chart
You run these — the chart only connects
Data flow
Your apps send OTLP to the Collector, which writes into Doris. Orbtrace reads telemetry back from Doris, and keeps its own settings and cache in Postgres + Valkey — bundled by default, or pointed at an external VM/managed instance.
Each of the three datastores can be bundled in-cluster or pointed at something you run outside it. Here is exactly what you get out of the box and what you supply yourself:
| Component | What it's for | Chart default | You supply it when… |
|---|---|---|---|
| Orbtrace server | The app | Always deployed | never |
| Postgres + pgvector | Settings, users, RCA vectors | Bundled in-cluster (postgres.mode: bundled) | you set postgres.mode: external |
| Valkey (or Redis) | Cache | Bundled in-cluster (valkey.mode: bundled) | you set valkey.mode: external |
| Doris | Telemetry store (logs / traces / metrics) | Not deployed (doris.mode: external) | always — set doris.host |
| Collector | Telemetry ingest | Never deployed | always — run it separately |
What Orbtrace needs to run
Orbtrace has four runtime dependencies. The chart bundles the first two; you always provide the last two:
- Postgres 18 + pgvector — settings, users, and the RCA vector store. ("pgvector" is just Postgres with the
vectorextension enabled — nothing exotic to install.) - Valkey (or any Redis-compatible server) — the cache. Orbtrace talks to it over the Redis protocol, so plain Redis works in place of Valkey.
- Apache Doris — the telemetry store for logs, traces, and metrics. Always external to the chart.
- An OpenTelemetry Collector — ingest. Orbtrace never receives OTLP itself; a Collector writes your telemetry into Doris. See Integration patterns.
For the cluster you also need Helm 3.8+, a fast SSD-backed StorageClass, and — on every node a Doris BE runs on — the kernel settings (vm.max_map_count ≥ 2000000, swap off). The full Doris requirements are on the Setting up Doris page.
Our recommended architecture
For production we recommend running the stateful databases outside Kubernetes — on VMs your DBAs manage, or managed services — and letting Helm deploy only the stateless app:
In Kubernetes — Helm deploys
Outside the cluster — you manage
Your apps send OTLP to the Collector, which writes into Doris. The stateless Orbtrace app in the cluster reads telemetry back from Doris and keeps its settings + cache in Postgres + Valkey. Only the app (and the ephemeral Valkey cache) live inside Kubernetes; the stores holding data you can't lose stay outside it.
| Component | Recommended for production | Also supported |
|---|---|---|
| Orbtrace server | In Kubernetes, via this Helm chart | — |
| Apache Doris | VM / managed, or the doris-operator in-cluster | bundled StatefulSet (dev/eval only) |
| Postgres + pgvector | VM or managed service | bundled in-cluster (postgres.mode: bundled) |
| Valkey (or Redis) | bundled in-cluster — it's only an ephemeral cache | VM / managed |
| Collector | a container alongside the cluster | your existing OTel pipeline |
Why keep the databases outside the cluster?
Postgres and Doris hold data you can't recreate — your settings and all your telemetry. Kubernetes is built for stateless apps you can delete and redeploy freely; databases are the opposite. Keeping them outside the cluster protects that data and keeps them easy to operate:
- A wrong
helm uninstallcan't delete your data. When a database runs in-cluster, its disk (a PersistentVolumeClaim) belongs to the Helm release — remove the release or the namespace and the volume, with all your telemetry, can be deleted with it. A database on a VM or managed service is never in reach of a Helm command. - Day-2 database work stays where it belongs. Backups, version upgrades, failover, and tuning are routine database chores your DBAs — or a managed service like RDS — already handle. Bundled in-cluster, that work lands on your Kubernetes team instead, and every database restart or upgrade now competes with the app for the same nodes.
- On OpenShift, no security-policy friction. OpenShift's default
restricted-v2policy blocks much of what database images expect (fixed user IDs, volume ownership), so a bundled database needs extra workarounds just to start. An external database sidesteps that entirely.
Valkey is the exception. It holds only cache — data that is rebuilt automatically and safe to lose — so there is nothing to protect. Leaving it bundled in-cluster is fine even in production.
To wire the app at externally-run stores, put these in your my-values.yaml — a small overrides file layered on the chart's own defaults (see Install with Helm). The chart's values.yaml is the base automatically, so you only list the keys you change. Replace every <…> with your own value; the rest are defaults you can leave as-is:
postgres:
mode: external
host: <your-postgres-host> # VM / managed Postgres+pgvector, reachable from the cluster
port: 5432 # default — change only if yours differs
database: orbtrace # the DB you created — any name works, this is just the default
username: orbtrace # the user you created — likewise your choice
password: <your-postgres-password> # or use existingSecret instead of a plaintext password
# Valkey stays bundled by default (recommended). To externalize it too, uncomment:
# valkey:
# mode: external
# host: <your-valkey-or-redis-host>
# port: 6379
doris:
mode: external # default — the chart never runs Doris
host: <your-doris-fe-host> # FE address of your VM / managed / operator Doris
queryPort: 9030 # default Doris MySQL query port
httpPort: 8030 # default Doris HTTP (Stream Load) portRunning a PoC?
If you have a VM or laptop with Docker, the simplest trial is Docker Compose: one docker compose up -d brings up Doris, Postgres, and Valkey with the app — no operator, no external datastore.
If your environment is Kubernetes and you want to evaluate there, Compose isn't an option — you still need Doris. The lightest path is Helm with a minimal in-cluster Doris: the doris-operator with a small 1-FE / 1-BE DorisCluster, or point doris.host at any Doris you already run. See Setting up Doris. (The bundled Postgres and Valkey need nothing extra for a trial.)
Steps to deploy on Kubernetes
Work through these in order:
- Provide the datastores — bring Postgres + pgvector and Valkey (bundled, VM/managed, or Docker).
- Setting up Doris — the telemetry store the chart never deploys (operator, VM/managed, or Compose for eval).
- Install with Helm — authenticate, edit values,
helm install, and verify. - OpenShift / OKD — if you're on OpenShift, the SCC overlay and node tuning.
- Ports & exposure — how to reach Orbtrace and change any port.
Once Orbtrace is up, wire your telemetry in — the Collector is the last of the two pieces you run yourself. Stand up a new OTel Collector, or just add Orbtrace's dorisexporter to your existing OTel pipeline (no re-platforming). Both paths, with the reference Collector config, are in Integration patterns.
Running on a managed cloud cluster (EKS / AKS / GKE)? See Deploying on Cloud for the provider-specific choices.