A Helm chart that runs Ubiquiti’s UniFi OS Server in Kubernetes — letting you self-host the UniFi Network application (the controller for switches, APs, gateways, etc.) without buying a UniFi Console. This is the successor to the standalone Network Application that Ubiquiti previously offered.
UniFi OS Server does not support UniFi Protect (cameras), Access, Talk, or Connect — those still require a UniFi Console.
The upstream runtime model (systemd managing ~15 tightly coupled services) is
kept intact. PostgreSQL and RabbitMQ are exposed as explicit, replaceable
dependencies (bundled subcharts or external instances). MongoDB runs embedded
inside the container via the bundled mongodb.service — it is hardcoded by
UniFi and cannot be externalized.
Warning — this project is experimental and not suitable for production yet. There’s a lot of AI work I don’t have time to verify all of.
Installer binary
└─ Podman container
└─ systemd
├─ unifi-core (Node.js — platform API)
├─ unifi (Java — Network controller)
├─ ulp-go (Go — identity platform)
├─ nginx (reverse proxy / TLS)
├─ postgresql (embedded)
├─ mongodb (embedded)
├─ rabbitmq + epmd (embedded)
└─ 7 more identity/agent services …
Helm release
├─ StatefulSet (single container, upstream systemd startup)
│ └─ unifi-os image (unifi-core, unifi, ulp-go, nginx, identity services,
│ mongodb — embedded, not externalized)
├─ PostgreSQL (CloudNativePG subchart or external)
└─ RabbitMQ (CloudPirates subchart or external)
This chart is built on HULL, which means
almost every Kubernetes object (services, routes, secrets, env vars, resource limits,
etc.) is defined as data in charts/unifi-os/values.yaml under hull.objects. You can override
or extend any object in your own values file without forking the chart. Values
that need Helm template logic use the _HT! prefix for inline Go Helm templates.
| Path | Purpose |
|---|---|
| Dockerfile | Extracts the upstream OCI image and repackages it as a standard Docker image. |
| Makefile | Build/push the image, extract configs, dump systemd maps. |
| Chart.yaml | Helm chart definition (app version 5.1.21) with subchart dependencies. |
| values.yaml | Primary chart values — StatefulSet, services, secrets, Gateway API routes. |
| values.env.example.yaml | Environment-specific overrides (registry, passwords, hostnames). |
| SERVICES.md | Reference for every UniFi OS service, its role, and dependencies. |
| DATABASE.md | PostgreSQL setup — bundled CNPG and external, credential options. |
| TLS.md | TLS certificate options — self-signed, existing secret, cert-manager. |
charts/unifi-os/templates/ |
HULL entrypoint, helpers, and Postgres override secrets. |
scripts/ |
Extraction utilities for reverse-engineering the upstream image. |
postgres.enabled: true)unifi.tls.certManager.enabled: true (optional but recommended)cp values.env.example.yaml values.env.yaml
Set credentials for PostgreSQL and RabbitMQ. The recommended approach is
existingSecretPrefix for PostgreSQL (no plaintext in Helm values) — see
DATABASE.md for full details. Minimal plaintext example:
global:
postgres:
connection:
password: "your-pg-password"
rabbitmq:
connection:
password: "your-rabbit-password"
erlangCookie: "your-erlang-cookie"
helm repo add unifi-os https://connorsapps.github.io/unifi-os-helm
helm repo update
helm upgrade -n unifi --create-namespace unifi unifi-os/unifi-os --install \
-f values.env.yaml
The chart includes opt-in support for:
Prometheus metrics via unpoller — scrapes UniFi OS and exposes metrics for Prometheus. Three auth options:
API key (recommended, UniFi OS 4+) — generate at Settings > Admins & Users > (your user) > API Key:
unifiExporter:
enabled: true
config:
apiKey: "your-api-key"
Username + password — create a local Viewer user at Settings > Admins & Users > Add Admin > Local Access Only:
unifiExporter:
enabled: true
config:
username: "metrics"
password: "change-me"
Pre-existing Secret — secret must contain a password key, an api-key key, or both; whichever is non-empty is used (api-key takes priority):
unifiExporter:
enabled: true
config:
username: "metrics" # required when using password auth
existingSecret:
name: "my-unifi-exporter-secret"
passwordKey: password # default
apiKeyKey: api-key # default
Additional collection options (all default to false):
| Field | What it collects |
|---|---|
saveEvents |
Client connect/disconnect and network events |
saveAlarms |
Security and network alarms |
saveAnomalies |
Detected network anomalies |
saveIds |
Device ID-to-name label mappings |
hashPii |
Hash MAC addresses and client names (privacy/compliance) |
BackendTLSPolicy for re-encrypted backend traffic. See TLS.md.All are disabled by default. See values.env.example.yaml and the relevant sections in values.yaml to enable them.
This project is not affiliated with, endorsed by, or sponsored by Ubiquiti Inc. “UniFi” and “UniFi OS” are trademarks of Ubiquiti Inc. This repository is independent community work for self-hosting purposes. Use at your own risk. There’s some AI ducktape holding this project together.