Cloudflare Workers
Deploy chmonitor to Cloudflare Workers for globally distributed, serverless hosting with D1 and Cron Trigger support.
Deploy chmonitor to Cloudflare Workers — best for globally cached, serverless hosting with no servers to manage.
The dashboard app (apps/dashboard) uses the @cloudflare/vite-plugin to build a native Cloudflare Workers bundle — no OpenNext adapter required. The deploy script is just pnpm run build && wrangler deploy.
Prerequisites
What you need
- Cloudflare account
- pnpm installed locally or in CI
CLOUDFLARE_API_TOKENwith Workers deploy permissions (or runwrangler loginfor OAuth)
One-click deploy
This deploys the apps/dashboard worker. Set the three ClickHouse vars when prompted. Full list: Environment variables.
Setup
Clone and install
git clone https://github.com/chmonitor/chmonitor.git
cd chmonitor/apps/dashboard
pnpm installSet ClickHouse secrets
wrangler secret put CLICKHOUSE_HOST
wrangler secret put CLICKHOUSE_PASSWORDBuild and deploy
pnpm run cf:deploy # vite build → wrangler deployOpen your Worker URL
Open your Workers URL or set a custom domain in the Cloudflare dashboard.
Verify
Open your Workers URL. To confirm from the shell, hit the readiness endpoint:
curl -sf https://<your-worker-url>/api/healthz && echo OKHow configuration works on Cloudflare
Build-time vs runtime vars
There are two kinds of variables — mixing them up is the most common source of bugs.
| Kind | Where to set | Who reads it | Example |
|---|---|---|---|
| Build-time | CI / shell before pnpm run build | Browser (derived VITE_*) | CHM_AUTH_PROVIDER, CHM_CLERK_PUBLISHABLE_KEY |
| Runtime | .env.production (hosted) or wrangler secret put | Worker | CLICKHOUSE_HOST, LLM_API_KEY, CLERK_SECRET_KEY |
Set CHM_* once. Do not also set VITE_*. Hosted dashboard wrangler.toml has no [vars] block — edit .env.production.
One canonical name
You usually don't set VITE_* directly. Set the canonical CHM_* name (e.g. CHM_AUTH_PROVIDER) in the build environment and vite.config.ts derives the matching VITE_*. A dual-surface setting must be present at build time (so the VITE_* inlines) and as a runtime [var] (so the server reads CHM_*) — same name, both places. See One canonical name per setting.
Runtime Worker vars (wrangler.toml [vars] and secrets) are never visible in the browser.
Secrets
wrangler secret put CLICKHOUSE_HOST
wrangler secret put CLICKHOUSE_PASSWORDOptional secrets (CLERK_SECRET_KEY, ANYROUTER_API_KEY, CRON_SECRET, …):
see Environment variables.
Redeploy after secret changes
After wrangler secret put, redeploy so the Worker picks up the change: pnpm run cf:deploy.
Configure
Required: CLICKHOUSE_HOST, CLICKHOUSE_USER, CLICKHOUSE_PASSWORD.
Template: apps/dashboard/.env.example.
Full names: Environment variables.
Auth: Authentication. Conversations: Conversation storage.
Deploy
pnpm run cf:deployThis runs: vite build (produces the Cloudflare Workers bundle) → wrangler deploy.
CI (GitHub Actions): push to main triggers .github/workflows/cloudflare.yml. Set CLOUDFLARE_API_TOKEN as a repository secret, plus CLICKHOUSE_*, and any canonical build-time vars (e.g. CHM_AUTH_PROVIDER, CHM_CLERK_PUBLISHABLE_KEY — the client VITE_* derive from them).
This repo's hosted deploy uses .env.production
Dashboard wrangler.toml declares no [vars]. Non-secret hosted config lives in apps/dashboard/.env.production (+ .env.preview). Edit that file — do not re-add [vars].
Preview locally
pnpm run cf:previewCloudflare bindings
The app uses these Cloudflare resources (configured in wrangler.toml):
| Binding | Type | Purpose |
|---|---|---|
CHM_CLOUD_D1 | D1 Database | Conversation history (optional) |
AGENT_CONVERSATIONS_DO | Durable Object | Conversation history via Durable Objects (optional) |
The TanStack Start build via @cloudflare/vite-plugin does not require KV, R2, or cache-tag bindings. Only conversation-store bindings need to be added if you enable server-side persistence.
Upgrading
Worker secrets persist across deploys; you only need to re-run wrangler secret put when a value changes.
For breaking changes between major versions, see Migrating to v0.3.