Self-hosting on Kubernetes
openZro ships a Helm chart so you can deploy the full self-hosted control plane (management, signal, relay, dashboard, embedded Dex IdP) on any Kubernetes cluster — managed (EKS, GKE, AKS, DOKS) or self-managed (k3s, kubeadm, Talos, Rancher).
This section covers the chart-based deployment path. For Docker Compose on a single VM, see the Quickstart Guide. For bare-metal multi-node installs via Ansible, see openzro-ansible.
When to choose Kubernetes
| Scenario | Use Kubernetes | Use Docker Compose |
|---|---|---|
| You already operate Kubernetes | ✅ Native fit | ⚠️ Extra moving piece |
| You want HA out of the box | ✅ Multi-replica per component | ❌ Single host |
| You need declarative GitOps | ✅ Operator + CRDs | ❌ Compose files |
| You need autoscaling | ✅ HPA on relay/signal | ❌ Vertical only |
| You want a 5-minute first install | ⚠️ ~15min including ingress | ✅ 5min flat |
| You're prototyping on a laptop | ⚠️ k3d / kind works but heavy | ✅ Single command |
What's included in the chart
The openzro Helm chart
deploys the control plane as a single release:
- management — account / peer / policy API (Deployment in
single-node mode, StatefulSet when
cluster.mode=embedded) - signal — gRPC peer-to-peer signaling. Exposed as a
LoadBalancerService with TLS terminated on the binary (recommended for ingress-nginx operators) OR via Ingress on controllers that handle gRPC streaming correctly (Envoy, Traefik, NGINX-Plus). See High availability - relay — TCP/WebSocket relay with TLS termination (cert-
manager-provisioned cert) and multi-pod fabric. Always exposed
as a
LoadBalancerService — Ingress is not supported (TCP persistent, idle timeouts kill connections). - dashboard — React SPA (Deployment, nginx)
- dex — embedded federated IdP (Deployment, via subchart)
Storage is external — the chart no longer bundles Postgres or MySQL subcharts. Point at Cloud SQL, RDS, or any reachable PostgreSQL. See Storage.
Routing peers (gateways, exit nodes) are not part of this
chart — they're data plane and live independently. Deploy them
via the openZro operator using the
OZRoutingPeer CRD.
Architecture choices
The chart embeds these design decisions; see the linked ADRs for the full rationale:
- Embedded Dex IdP — every install ships with a federated IdP out of the box. Operators configure connectors (Google, GitHub, Microsoft, Keycloak, Okta, generic OIDC) at runtime via the dashboard. See ADR-0006.
- Helm chart + Kubernetes operator — chart for the control plane, operator for the data plane. See ADR-0008.
- Multi-pod relay fabric — when
relay.replicaCount > 1the chart auto-wires inter-pod TCP forwarding so peers connected to different pods can still reach each other, with an HMAC- authenticated control plane between pods. See ADR-0014.
Section contents
- Helm Quickstart — install in 15 minutes from a fresh cluster
- High Availability — multi-replica
management/signal, multi-pod relay, the
cluster.modeswitch - Storage Backends — PostgreSQL or MySQL via the bundled subcharts, manual DSN config for external databases
- Upgrades —
helm upgradeworkflow + CRD upgrade gotchas
The Helm chart is published on every tag push to
https://openzro.github.io/helms
and as an OCI artifact at oci://ghcr.io/openzro/charts/openzro.
Both paths produce the same chart.