Same Docker image, in-cluster. Chart ships with the repo. Non-root uid 1001, port 3000.
Single node? Use Docker instead.
Prerequisites
- A Kubernetes cluster and a working
kubectlcontext. - Helm 3.
- A reachable ClickHouse HTTP endpoint and a read-only monitoring user (
SELECT/SHOWon the databases you monitor). Do not assign ClickHouse’sreadonly=1profile — the dashboard setsmax_execution_timeas a session setting, and that profile forbids it (readiness then stays 503).
Steps
1. Add the chart repo and install
helm repo add chmonitor https://charts.chmonitor.dev
helm repo update
helm install my-chm chmonitor/chmonitor \
--set clickhouse.host="https://clickhouse.example.com:8443" \
--set clickhouse.user="monitoring" \
--set clickhouse.password="change-me"
--set is fine to try it. For real installs use a values file and a Secret (steps 2 and 3).
OCI instead of the Helm repo:
helm install my-chm oci://ghcr.io/chmonitor/chmonitor --version vX.Y.Z \
--set clickhouse.host="https://clickhouse.example.com:8443" \
--set clickhouse.user="monitoring" \
--set clickhouse.password="change-me"
Replace vX.Y.Z with a release tag. Pin it — do not rely on :latest.
2. Prefer a values file
# values.yaml — do not commit real passwords
image:
tag: "vX.Y.Z"
clickhouse:
host: "https://clickhouse.example.com:8443"
user: "monitoring"
password: "change-me"
ingress:
enabled: false
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
cpu: 500m
memory: 512Mi
helm install my-chm chmonitor/chmonitor -f values.yaml
Upgrade later with the same file:
helm upgrade my-chm chmonitor/chmonitor -f values.yaml
3. Put the password in a Secret
kubectl create secret generic chmonitor-clickhouse \
--from-literal=CLICKHOUSE_PASSWORD='change-me'
Then point the chart at it instead of clickhouse.password:
clickhouse:
host: "https://clickhouse.example.com:8443"
user: "monitoring"
existingSecret: chmonitor-clickhouse # key: CLICKHOUSE_PASSWORD
Do not put the password in git. External Secrets, SOPS, or Sealed Secrets if you already use them.
4. Expose it (optional)
ingress:
enabled: true
className: nginx
hosts:
- host: chmonitor.example.com
paths:
- path: /
pathType: Prefix
Until then, port-forward is enough.
Verifying it worked
Two probes. If liveness hits ClickHouse, a CH blip CrashLoopBackOffs the pod:
| Probe | Path | Meaning |
|---|---|---|
| Liveness | GET /healthz |
Process is up. Always 200 while the app runs. Never gate this on ClickHouse. |
| Readiness | GET /api/healthz |
Can reach ClickHouse (SELECT 1). 503 keeps the pod out of the Service. |
kubectl rollout status deploy/my-chm-chmonitor
kubectl port-forward svc/my-chm-chmonitor 3000:3000
curl -sf http://localhost:3000/api/healthz && echo OK
Open http://localhost:3000. A 200 on /api/healthz means the dashboard can talk to ClickHouse, not only that the container started.
Uninstall:
helm uninstall my-chm
Related
- Docs: Kubernetes — full values, autoscaling, kustomize.
- Self-hosting on Docker — the single-container path.
- Self-hosting on Kubernetes — Helm plus kustomize, same probes.
- chmonitor selling commercial license if you need an invoice. The chart is still GPL-3.0.