chmonitorchmonitor
Deployment

Cloudflare Workers

Deploy chmonitor to Cloudflare Workers for globally distributed, serverless hosting with D1 and Cron Trigger support.

Deploy to Cloudflare Workers — globally cached, serverless, no servers. The dashboard (apps/dashboard) uses @cloudflare/vite-plugin for a native Workers bundle. Deploy is pnpm run build && wrangler deploy.

Loading diagram…

Prerequisites

What you need

  • Cloudflare account
  • pnpm locally or in CI
  • CLOUDFLARE_API_TOKEN with Workers deploy permissions (or wrangler login)

One-click deploy

Deploy to Cloudflare

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 install

Set ClickHouse secrets

wrangler secret put CLICKHOUSE_HOST
wrangler secret put CLICKHOUSE_PASSWORD

Build and deploy

pnpm run cf:deploy   # vite build → wrangler deploy

Open your Worker URL

Open the Workers URL or attach a custom domain in the Cloudflare dashboard.

Verify

curl -sf https://<your-worker-url>/api/healthz && echo OK

How configuration works on Cloudflare

Build-time vs runtime vars

Mixing these two kinds is the most common source of bugs.

KindWhere to setWho reads itExample
Build-timeCI / shell before pnpm run buildBrowser (derived VITE_*)CHM_AUTH_PROVIDER, CHM_CLERK_PUBLISHABLE_KEY
Runtime.env.production (hosted) or wrangler secret putWorkerCLICKHOUSE_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

Set the canonical CHM_* name in the build environment; vite.config.ts derives VITE_*. Dual-surface settings must exist at build time (inline) and as a runtime var (server). See One canonical name per setting.

Runtime Worker vars and secrets are never visible in the browser.

Secrets

wrangler secret put CLICKHOUSE_HOST
wrangler secret put CLICKHOUSE_PASSWORD

Optional (CLERK_SECRET_KEY, ANYROUTER_API_KEY, CRON_SECRET, …): Environment variables.

Redeploy after secret changes

After wrangler secret put, redeploy: 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:deploy

Runs vite build → wrangler deploy.

CI: push to main runs .github/workflows/cloudflare.yml. Set CLOUDFLARE_API_TOKEN, CLICKHOUSE_*, and build-time CHM_* (e.g. CHM_AUTH_PROVIDER, CHM_CLERK_PUBLISHABLE_KEY).

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:preview

Cloudflare bindings

BindingTypePurpose
CHM_CLOUD_D1D1 DatabaseConversation history (optional)
AGENT_CONVERSATIONS_DODurable ObjectConversation history via Durable Objects (optional)

TanStack Start via @cloudflare/vite-plugin does not need KV, R2, or cache-tag bindings. Add conversation-store bindings only if you persist chats server-side.

Upgrading

Rebuild and deploy

pnpm run cf:deploy

Worker secrets persist across deploys; re-run wrangler secret put only when a value changes.

For breaking changes, see Migrating to v0.3.

Troubleshooting

On this page