This is for anyone who wants a ClickHouse dashboard running against their own cluster without handing credentials to a third party. chmonitor’s Docker image is the same codebase as the hosted Cloud product — self-hosted just means you run the container yourself. By the end you’ll have it up on localhost:3000 and pointed at a real cluster.
Prerequisites
- Docker installed and running.
- A reachable ClickHouse endpoint and a monitoring user with
SELECTonsystem.*. - A release tag to pin (browse releases — avoid
:latestin anything you plan to keep running, since an unpinned tag drifting under you is a real failure mode, not a hypothetical).
Steps
1. Pull and run
docker run -d --name chmonitor -p 3000:3000 \
--add-host=host.docker.internal:host-gateway \
-e CLICKHOUSE_HOST='http://host.docker.internal:8123' \
-e CLICKHOUSE_USER='monitoring' \
-e CLICKHOUSE_PASSWORD='change-me' \
ghcr.io/chmonitor/chmonitor:vX.Y.Z
Replace vX.Y.Z with a real release tag. The --add-host flag is only needed on Linux, when ClickHouse runs on the same Docker host — Docker Desktop for Mac/Windows already resolves host.docker.internal without it.
Open http://localhost:3000.
2. Or use Docker Compose
services:
chmonitor:
image: ghcr.io/chmonitor/chmonitor:vX.Y.Z
ports:
- '3000:3000'
environment:
CLICKHOUSE_HOST: 'http://clickhouse:8123'
CLICKHOUSE_USER: 'monitoring'
CLICKHOUSE_PASSWORD: 'change-me'
healthcheck:
test: ['CMD', 'wget', '-q', '-O', '/dev/null', 'http://localhost:3000/api/health']
interval: 30s
timeout: 5s
start_period: 20s
retries: 3
If ClickHouse runs in the same Compose project, use the service name (clickhouse above) as the host directly — no host.docker.internal needed.
3. Point it at more than one host (optional)
CLICKHOUSE_HOST accepts a comma-separated list; CLICKHOUSE_USER and CLICKHOUSE_PASSWORD can each be a single value applied to every host, or one value per position:
-e CLICKHOUSE_HOST='http://ch1:8123,http://ch2:8123' \
-e CLICKHOUSE_USER='monitoring,monitoring' \
-e CLICKHOUSE_PASSWORD='pass1,pass2' \
-e CLICKHOUSE_NAME='shard-1,shard-2'
4. Adjust query timeouts and pool size (optional)
-e CLICKHOUSE_MAX_EXECUTION_TIME='30' \
-e CLICKHOUSE_POOL_SIZE='10'
Defaults are a 60s query timeout and a pool size of 10 — raise the timeout if your workload has legitimately slow diagnostic queries, or the pool size if many people are hitting the dashboard concurrently.
Verifying it worked
curl -sf http://localhost:3000/api/healthz && echo OK
/api/healthz is the readiness probe — it checks the container is up and that it can reach ClickHouse, so a green result here means the whole path is working, not just that the container started.
Related
- Docs: Docker deployment — the full reference for this walkthrough, including feature-flag configuration via env vars or a mounted TOML file.
- Docs: Production checklist — before putting a self-hosted instance in front of real users.
- Docs: Kubernetes deployment — if you outgrow a single container.