Installation
There are three ways to install CHOps. Use the one that fits you.
- Docker is the fastest way to a running instance. You pull a published image and run it, with no Bun needed on the host.
- A prebuilt binary is one file with no runtime dependencies. It is good for a server or to hand to a teammate.
- From source with Bun is for development or to run the latest code.
Every method needs the same four values and uses the same first-login and connection steps. Read "Before you begin" and "Required configuration" first, then go to the method you want.
Before you begin
Every method needs a reachable ClickHouse® server. You need Bun for the source method and to build a binary, but a prebuilt binary runs without it. The Docker method needs Docker.
1. A reachable ClickHouse® server. Tested on 26.3 LTS and 26.8 LTS. Older and newer versions should work, but they are not tested. CHOps talks to ClickHouse® over its HTTP interface. The default HTTP port is 8123, not the native port 9000. Confirm the server is reachable from the machine that runs CHOps:
curl http://your-clickhouse-host:8123/pingIf it prints Ok., the server is reachable.
2. Bun 1.4.2 (source and binary build methods only). Bun is the JavaScript runtime CHOps is built on. Install the tested version:
curl -fsSL https://bun.com/install | bash -s "bun-v1.4.2"Close and reopen your terminal. Then check the version:
bun --version3. Docker (Docker method only). Install Docker Engine with the Compose plugin. You do not need Bun for this method.
Required configuration
CHOps checks its environment at startup and exits at once if a required value is missing. Four values are required in every method:
| Variable | Purpose |
|---|---|
SUPER_ADMIN_1 | The user name of the first super admin. This is your first login. |
SUPER_ADMIN_1_PASSWORD | The password for that account. Use a strong one. |
SUPER_ADMIN_1_EMAIL | The email for that account. The server does not start without it. |
ENCRYPTION_SECRET | A random string of 32 characters or more. It makes the key that encrypts stored ClickHouse® passwords, the system email password, and AI provider keys. Make one with openssl rand -hex 32. Never change it after the first start. |
Everything else has a default. A minimal configuration looks like this:
SUPER_ADMIN_1=admin
SUPER_ADMIN_1_PASSWORD=change_me_to_a_strong_password
SUPER_ADMIN_1_EMAIL=you@example.com
ENCRYPTION_SECRET=paste_output_of_openssl_rand_hex_32_hereDo not change
ENCRYPTION_SECRETafter the first run. It is the encryption key for every stored ClickHouse® password. If you change it, those saved credentials become unreadable, and you must enter them again.
The Configuration page lists every variable.
Method A: Run with Docker
We publish the image to two public registries. Pull the image and run it, with nothing to build.
docker run -d --name chops -p 3000:3000 \
-e ENCRYPTION_SECRET="$(openssl rand -hex 32)" \
-e SUPER_ADMIN_1=admin \
-e SUPER_ADMIN_1_PASSWORD=change_me_to_a_strong_password \
-e SUPER_ADMIN_1_EMAIL=you@example.com \
-v chops-data:/app/data \
quantrailadmin1/ch-ops:latestThen open http://localhost:3000. The image is also on GitHub Container Registry: ghcr.io/quantrail-data/ch-ops:latest. Both registries also have a tag for each release version.
The container runs as a non-root user, serves a health check at /api/health, and keeps the SQLite database in the chops-data volume across restarts.
Method B: Run with Docker Compose
Make a file named docker-compose.yml with the content below. Change the encryption secret and the admin password first.
services:
chops:
image: quantrailadmin1/ch-ops:latest
container_name: chops
restart: unless-stopped
ports:
- "3000:3000"
environment:
- ENCRYPTION_SECRET=replace-with-a-long-random-value
- SUPER_ADMIN_1=admin
- SUPER_ADMIN_1_PASSWORD=change_me_to_a_strong_password
- SUPER_ADMIN_1_EMAIL=you@example.com
volumes:
- chops-data:/app/data
volumes:
chops-data:Start it:
docker compose up -dThen open http://localhost:3000. To stop CHOps, run docker compose down. Your data stays in the chops-data volume.
Method C: Run a prebuilt binary
Prebuilt binaries for Linux, macOS, and Windows are on the Releases page. Download the file for your platform (chops-linux-x64, chops-darwin-arm64, or chops-windows-x64.exe). Then run it with the required variables:
chmod +x chops-linux-x64
SUPER_ADMIN_1=admin \
SUPER_ADMIN_1_PASSWORD=change_me_to_a_strong_password \
SUPER_ADMIN_1_EMAIL=you@example.com \
ENCRYPTION_SECRET=$(openssl rand -hex 32) \
./chops-linux-x64The binary makes data/chops.db and data/crypto.salt in its working directory at startup.
Method D: Install from source
Use this method for development or to run the latest code.
Step 1: Get the code and install dependencies
git clone https://github.com/Quantrail-Data/CH-Ops.git
cd CH-Ops
bun installbun install downloads every library CHOps needs. The first run can take a minute.
Step 2: Make your configuration file
Copy the example and edit it:
cp .env.example .envSet the four required values from the Required configuration section. The example file ships with DISABLE_ENV_LOGIN=true, which turns off the .env password fallback so only accounts in the app database can log in. That is safe from the start, because CHOps seeds the first super admin into the app database on the first run (see Step 3). To keep the .env fallback during setup, set DISABLE_ENV_LOGIN=false.
Step 3: Set up the database
CHOps stores its own settings in a small SQLite database. Make it:
bun run db:migrateYou see "Database migration complete." The migration makes data/chops.db and seeds your SUPER_ADMIN_1 account. The server also runs this migration at each start, so this step is optional.
Step 4: Start CHOps
Development mode rebuilds on code changes and runs the backend API on port 3000 and the Vite frontend on port 5173:
bun run devOpen http://localhost:5173.
Production mode builds the frontend once and serves everything from one process on port 3000:
bun run build
bun src/backend/server.jsOpen http://localhost:3000. The bun run build step is required. Without it, the server answers "Frontend not built."
Build your own image or binary
Build only if you change the code, or make your own image or binary.
Build a Docker image. The build itself does not need a .env file, but the repository docker-compose.yml builds the image and reads run-time settings from .env through env_file, so make a .env with the four required variables first, then:
docker compose up -d --buildOr build and run by hand:
docker build -t chops:latest .
docker run -d --name chops -p 3000:3000 --env-file .env -v chops-data:/app/data chops:latestBuild a standalone binary.
bun run build:binary # your current platform
bun run build:binary:linux # chops-linux-x64
bun run build:binary:mac # chops-darwin-arm64
bun run build:binary:windows # chops-windows-x64.exeMake a dedicated ClickHouse® user
For anything beyond local testing, do not connect CHOps as the ClickHouse® default user. Make a dedicated user and a role. Grant only the privileges CHOps needs.
The project ships a complete, role-based grant script at clickhouse-user-setup.sql. Run it as a ClickHouse® admin and change the password. The script makes the role chops_admin with these grants, and gives the role to the user chops:
GRANT SELECT ON *.* TO chops_admin; -- read system tables and user data
GRANT SHOW ON *.* TO chops_admin; -- SHOW DATABASES, SHOW CREATE TABLE, and so on
GRANT KILL QUERY ON *.* TO chops_admin; -- stop a running query
GRANT INTROSPECTION ON *.* TO chops_admin; -- the query profiler
GRANT BACKUP ON *.* TO chops_admin; -- BACKUP and RESTORE
GRANT ACCESS MANAGEMENT ON *.* TO chops_admin; -- the DB RBAC screens
GRANT ALTER INDEX ON *.* TO chops_admin; -- index management
GRANT ALTER PROJECTION ON *.* TO chops_admin; -- projection managementNotes:
SELECTandSHOWare the base. The other grants are for one feature each. You can remove the grant of a feature that you do not use.- The monitoring charts use the
merge()table function on system tables. It needs onlySELECT, so no extra grant is required. - The query profiler needs
INTROSPECTIONandallow_introspection_functions = 1, which the script sets for the user. The server must also havesystem.trace_logenabled. ACCESS MANAGEMENTis powerful. A user with it can make a new superuser. Remove it if you do not use the DB RBAC screens.- The script does not grant
S3orREMOTE. If your server checks these grants for table functions, addS3for the storage features (s3()) andREMOTEfor the cluster-wide views of Kubernetes Insights (clusterAllReplicas()).
The SQL Editor and Schema Studio use each person's own ClickHouse® credentials, entered at connect time. This account does not affect them.
First login and connecting to ClickHouse®
- Open CHOps in your browser. The port is 5173 in development, or 3000 in every other method.
- Log in with the
SUPER_ADMIN_1user name and password. You land on the Home page. - CHOps does not yet know where your ClickHouse® server is. Go to Control panel > Cluster Management.
- On the Direct connection tab, click New Cluster. Type a cluster name.
- Click Add Node. Enter a unique node name, the host or IP, the port (usually 8123, the HTTP port), the user (for example the
chopsuser), and the password. Check HTTPS if your server uses TLS. - Click the test button (plug icon) next to the node. On success you see the ClickHouse® version and uptime.
- Click Create Cluster. The navigation bar updates at once with no re-login.
You can configure up to 3 clusters, with a combined maximum of 18 nodes. Switch between them from the top bar. CHOps encrypts cluster passwords with AES-256-GCM before it stores them.
Verify it is working
-
Open Overview > Cluster Overview. You should see your ClickHouse® version and uptime.
-
Check the health endpoint. It confirms the server is up, independent of ClickHouse®:
curl http://localhost:3000/api/health # {"ok":true,"ts":"...","version":"..."} -
GET /api/versionreturns the running CHOps version.
Where your data lives
CHOps keeps all of its state in a SQLite database at data/chops.db. It also writes the WAL files (data/chops.db-wal and data/chops.db-shm) and a per-install data/crypto.salt for credential encryption. Stored passwords need the salt file and the same ENCRYPTION_SECRET. Back up the whole data/ directory to keep users, clusters, alerts, dashboards, and saved credentials. Stop CHOps before you copy the files, or use bun run db:backup. Under Docker, this directory is the chops-data volume at /app/data. For an automated off-site copy, see App Data Backup under Administration.
Run only one CHOps process for one data/ directory. Two processes on one database give wrong login limits and duplicate alerts.
Troubleshooting
The server exits at once with "Missing required env." One of the four required values is unset. Confirm SUPER_ADMIN_1, SUPER_ADMIN_1_PASSWORD, SUPER_ADMIN_1_EMAIL, and ENCRYPTION_SECRET are all set. Under Docker, only variables in the service environment: or an env_file: reach the container.
"Frontend not built." You started the production server without a build. Run bun run build, then bun src/backend/server.js. In development, use bun run dev.
"Cannot connect to ClickHouse®." Make sure the HTTP port (usually 8123) is reachable from the machine that runs CHOps. Use the HTTP port, not the native 9000. Test with curl http://your-host:8123/ping.
"Invalid credentials" at login. The user name and password must match SUPER_ADMIN_1 and SUPER_ADMIN_1_PASSWORD. After 5 failed attempts for the same user name within 15 minutes, the account locks for a time. Wait and try again.
Port already in use. Set a different port in .env, for example PORT=3001, and restart. In Docker, change the port mapping, for example -p 3001:3000.
Login worked before but stopped after a config change. If you changed ENCRYPTION_SECRET, CHOps can no longer decrypt the stored ClickHouse® passwords. Restore the original secret, or enter the affected credentials again.
A ENCRYPTION_SECRET shorter than 32 characters exits at startup. The encryption key derivation needs 32 characters or more. Make one with openssl rand -hex 32.
Next steps
- Configuration for every environment variable and the in-app connection bar.
- Production deployment to run behind Caddy with systemd.
- Building a Binary to distribute a single executable.