Install on Kubernetes (Helm)
Deploy the full self-hosted KubeWatch stack on Kubernetes with the Helm chart.
The KubeWatch Helm chart deploys the full self-hosted stack onto any Kubernetes cluster: the API gateway, all backend services, PostgreSQL, the metrics store, the event bus, and the dashboard.
Prerequisites
- Helm 3.10+
- Kubernetes 1.26+
- A default
StorageClassfor persistent volumes - An ingress controller (e.g. ingress-nginx or Traefik) for external access
Install
The chart is distributed as a packaged tarball, install it directly from the release URL (no helm repo add needed):
helm upgrade --install kubewatch \
https://raw.githubusercontent.com/lloyd-theophilus/kubewatch-releases/main/kubewatch.tgz \
--namespace kubewatch --create-namespace \
--set global.domain=kubewatch.example.com \
--set global.jwtSecret="$(openssl rand -hex 32)" \
--set [email protected] \
--set postgres.password="$(openssl rand -hex 16)" \
--set ingress.enabled=true \
--set ingress.className=nginx \
--set ingress.host=kubewatch.example.com \
--set ingress.tls=true
Using a values file (recommended)
Create kubewatch-values.yaml:
global:
domain: "kubewatch.example.com"
jwtSecret: "your-long-random-jwt-secret"
mode: selfhosted
admin:
email: "[email protected]"
# password: leave unset to auto-generate
postgres:
password: "your-postgres-password"
auth:
licenseKey: "" # optional; a 30-day trial starts automatically without one
ingress:
enabled: true
className: "nginx"
host: "kubewatch.example.com"
tls: true
Install with it:
helm upgrade --install kubewatch \
https://raw.githubusercontent.com/lloyd-theophilus/kubewatch-releases/main/kubewatch.tgz \
--namespace kubewatch --create-namespace \
-f kubewatch-values.yaml
Values reference
| Value | Default | Description |
|---|---|---|
global.domain | "" | Public domain the platform is served on |
global.jwtSecret | "" | Secret used to sign login sessions (set a long random value) |
global.mode | selfhosted | Deployment mode |
admin.email | [email protected] | Initial admin account email |
admin.password | "" | Initial admin password (auto-generated if empty) |
postgres.password | "" | PostgreSQL password |
auth.licenseKey | "" | License key (optional, 30-day trial without one) |
ingress.enabled | false | Create an Ingress resource |
ingress.className | nginx | Ingress class name |
ingress.host | kubewatch.example.com | Ingress hostname |
ingress.tls | false | Enable TLS on the Ingress |
Verify the installation
kubectl get pods -n kubewatch
All pods should reach Running. Initial startup takes a couple of minutes while the database initializes and migrations run.
If you didn't set an admin password, read the generated one. It's stored in the release's Secret, not the ConfigMap (sensitive values are deliberately kept out of the ConfigMap, which isn't encrypted at rest and is often synced to Git by GitOps tooling):
kubectl get secret kubewatch-secret -n kubewatch -o jsonpath='{.data.ADMIN_PASSWORD}' | base64 -d
Access the dashboard at your ingress host, or without an ingress:
kubectl port-forward -n kubewatch svc/kubewatch-gateway 8000:8000
Upgrading
helm upgrade --install kubewatch \
https://raw.githubusercontent.com/lloyd-theophilus/kubewatch-releases/main/kubewatch.tgz \
--namespace kubewatch \
-f kubewatch-values.yaml
Uninstalling
helm uninstall kubewatch -n kubewatch
# This does NOT delete PersistentVolumeClaims. To remove all data:
kubectl delete pvc -n kubewatch --all
Connecting agents
After the platform is up, log in and create an API key under Settings → API Keys. When you deploy agents, you must also point them at your own gateway with serverURL, otherwise they default to the hosted KubeWatch Cloud gateway and fail to register (the API key your self-hosted instance issued doesn't exist there):
helm upgrade --install kubewatch-agent \
https://raw.githubusercontent.com/lloyd-theophilus/kubewatch-releases/main/kubewatch-agent.tgz \
--namespace kubewatch --create-namespace \
--set apiKey=YOUR_API_KEY \
--set agentName=my-production-cluster \
--set serverURL=https://kubewatch.example.com
Use http://<your-server-ip> for serverURL if you're running on a bare IP with no domain/TLS yet. See Kubernetes Agent for the full agent guide, or Docker agent for non-Kubernetes hosts.