Self-host Provon On Cloudflare
Deploy Provon into your own Cloudflare account with independently scalable Workbench, API, Gateway, MCP, OTLP, telemetry pipeline, diagnostics, and maintenance deployments. This path replaces the Node process and local files with Cloudflare platform primitives; it is not a front end for a hosted management service.
When To Choose This Runtime#
| Decision | Cloudflare runtime |
|---|---|
| Workbench availability must not sit on the model-request path | Separate Pages and Workers |
| Ingest, summaries, and diagnostics must scale independently | Managed Queues with dedicated consumers |
| Metadata and usage events need a managed SQL database | Shared D1 databases |
| Telemetry should use object storage with SQL reads | R2 Data Catalog / Iceberg with R2 SQL |
| You operate Cloudflare resources and a CI deployment pipeline | Wrangler configs, release commands, and secret bindings |
Deployments And Backing Resources#
| Deployment | Entrypoint or config | Responsibility |
|---|---|---|
| Workbench Pages | services/cloudflare/workbench |
SvelteKit UI on Pages |
| API Worker | wrangler.api.toml |
Identity, sessions, control API, telemetry reads |
| Gateway Worker | wrangler.gateway.toml |
Model traffic, routing, policy, guardrails, usage state |
| MCP Worker | wrangler.mcp.toml |
Streamable-HTTP MCP ingress and hosted tool state |
| OTLP Worker | wrangler.otel.toml |
OTLP authentication, validation, staging, queueing |
| Telemetry Pipeline Worker | wrangler.telemetry-pipeline.toml |
Ingest, gateway-telemetry, and summary queue consumers |
| Diagnostics Worker | wrangler.diagnostics.toml |
Queued diagnosis execution and coordinator state |
| Maintenance Worker | wrangler.maintenance.toml |
Cron housekeeping: retention, metadata maintenance, work-item sync |
| Telemetry Warehouse Worker | wrangler.telemetry-warehouse.toml |
Internal deterministic shard routing for telemetry writes |
| Warehouse Container | Dockerfile.telemetry-warehouse |
Iceberg append, summary replacement, and retention |
The checked-in templates use provon-demo-* resource names for the public demo profile.
Keep those names isolated from any other Cloudflare account or deployment; never reuse
production resource IDs in demo configs.
Requirements#
- A Cloudflare account with the platform products used by the checked-in Wrangler configs, including Containers, R2 Data Catalog, and R2 SQL.
- Node.js 22 or newer, pnpm 10, and Wrangler 4 authenticated for the target account.
- Custom domains or routes for the Workbench, API, Gateway, MCP, and OTLP origins.
- API tokens for deployment, R2 SQL reads, and Data Catalog mutations.
- A secret manager or CI secret store for Worker secrets.
Check the CLI and account before provisioning:
pnpm exec wrangler --version
pnpm exec wrangler whoamiCloudflare product availability and limits change independently; confirm Containers, Data Catalog, and R2 SQL are enabled for the target account before committing to this topology.
Deployment Flow#
1. Prepare Wrangler Configs#
The .example.toml files declare the complete binding topology:
services/cloudflare/wrangler.api.example.toml
services/cloudflare/wrangler.gateway.example.toml
services/cloudflare/wrangler.mcp.example.toml
services/cloudflare/wrangler.otel.example.toml
services/cloudflare/wrangler.telemetry-pipeline.example.toml
services/cloudflare/wrangler.diagnostics.example.toml
services/cloudflare/wrangler.maintenance.example.toml
services/cloudflare/wrangler.telemetry-warehouse.example.tomlRender deployment configs from the repository templates:
pnpm release:planKeep neutral binding keys unchanged; fill real IDs and origins in the ignored
resources.local.json. Only templates and the non-secret Workbench build default are
versioned; actual resource coordinates stay local.
The pipeline reads PROVON_TELEMETRY_QUEUE_NAMES, a JSON mapping with the ingest,
gateway-telemetry, and telemetry-summary roles. The release render derives it from the
pipeline's queue references; resources.local.json cannot override the mapping, and missing,
duplicate, or unknown queue names fail closed. When using a Wrangler template directly, keep
the mapping equal to the queue names declared in queues.consumers.
2. Provision Storage And Queues#
pnpm release:resources prints the exact provisioning commands for the active profile and
applies only explicitly selected missing resources with --apply --names. The manual
equivalents are:
pnpm exec wrangler d1 create provon-demo-meta
pnpm exec wrangler d1 create provon-demo-metering
pnpm exec wrangler kv namespace create provon-demo-gateway-cache
pnpm exec wrangler r2 bucket create provon-demo-blobs
pnpm exec wrangler r2 bucket create provon-demo-telemetry
pnpm exec wrangler r2 bucket catalog enable provon-demo-telemetry
pnpm exec wrangler queues create provon-demo-ingest
pnpm exec wrangler queues create provon-demo-ingest-dlq
pnpm exec wrangler queues create provon-demo-telemetry-summary
pnpm exec wrangler queues create provon-demo-gateway-telemetry
pnpm exec wrangler queues create provon-demo-diagnostics
pnpm exec wrangler pages project create provon-demo-app --production-branch mainRecord both D1 database IDs, the KV namespace ID, the Data Catalog URI and warehouse name, and the account ID. Multiple Workers bind the same metadata D1 (API, Gateway, MCP, OTLP, pipeline, diagnostics, and maintenance); the usage-events D1 is shared by the API, pipeline, diagnostics, and maintenance deployments. Do not create per-worker copies of either database.
3. Bindings Matrix#
| Binding kind | API | Gateway | MCP | OTLP | Pipeline | Diagnostics | Maintenance | Warehouse |
|---|---|---|---|---|---|---|---|---|
Meta D1 (PROVON_META_DB) |
yes | yes | yes | yes | yes | yes | yes | — |
Usage-events D1 (PROVON_METERING_DB) |
yes | — | — | — | yes | yes | yes | — |
Blob R2 (PROVON_BLOB_BUCKET) |
yes | yes | — | yes | yes | yes | yes | — |
| Gateway cache KV | — | yes | — | — | — | — | — | — |
| Queue producers / consumers | — | gateway-telemetry producer | — | ingest, summary producers | all three consumers; ingest DLQ producer | diagnostics producer and consumer | — | — |
| Service bindings | Warehouse executor, Gateway runtime, MCP runtime | — | Warehouse executor | Warehouse executor | Warehouse executor | Warehouse executor, Gateway runtime | Warehouse executor | — |
| Durable Objects | Coordinator (remote) | Usage state, target state | Runtime state | — | Coordinator (remote) | Coordinator (local) | — | Executor container |
Worker-specific wiring notes:
- API: bind both D1 databases and the blob bucket; set R2 SQL coordinates; bind the
warehouse executor, Gateway runtime (
GatewayRuntimeEntrypoint), and MCP runtime (McpRuntimeEntrypoint); set Workbench origins and cookie policy. - Gateway: bind the meta D1, cache KV, blob bucket, and the gateway-telemetry producer;
preserve the
GatewayUsageStateDurableObjectandGatewayTargetStateDurableObjectclasses and their migrations. The API and diagnostics Workers reach the Gateway over thePROVON_GATEWAY_RUNTIMEservice binding; the Gateway needs no extra inbound route beyond its public origin. - MCP: bind the meta D1 and preserve
McpRuntimeStateDurableObject; the API reaches the MCP Worker overPROVON_MCP. - OTLP: bind the meta D1 and blob bucket; bind the ingest and summary producers and the warehouse service; use the same R2 SQL coordinates as the readers.
- Pipeline: bind both D1 databases, the blob bucket, the three queue consumers and the ingest DLQ producer, and the warehouse service; it does not call models.
- Diagnostics: bind both D1 databases, the diagnostics queue, the local coordinator Durable Object, the Gateway runtime service, and the warehouse service.
- Maintenance: bind both D1 databases and the blob bucket; preserve the cron trigger
(
0 */6 * * *). - Warehouse: set
PROVON_R2_CATALOG_URI,PROVON_R2_CATALOG_WAREHOUSE, R2 object coordinates, and the catalog token; preserve the Container and executor Durable Object bindings;workers_devstays disabled.
4. Configure Public Origins#
A typical split-domain layout:
| Deployment | Example |
|---|---|
| Workbench | https://app.provon.example |
| API | https://api.provon.example |
| Gateway | https://gateway.provon.example |
| MCP | https://mcp.provon.example |
| OTLP | https://otel.provon.example |
API Worker variables:
[vars]
PROVON_AUTH_ORIGIN = "https://api.provon.example"
PROVON_AUTH_TRUST_HOST = "true"
PROVON_AUTH_COOKIE_DOMAIN = ".provon.example"
PROVON_WORKBENCH_ORIGINS = "https://app.provon.example"Register sign-in and Connector OAuth callbacks on the public API origin:
https://api.provon.example/auth/callback/github
https://api.provon.example/auth/callback/google
https://api.provon.example/v1/integrations/github/callbackUse exact browser origins in PROVON_WORKBENCH_ORIGINS; do not use * for a credentialed
Workbench. The Pages build receives the API origin from resources.local.json origins.api.
5. Set Secrets#
Generate one stable PROVON_AUTH_SECRET for this deployment and set it on every runtime that reads
sessions or encrypted project credentials. Keep per-worker secret JSON files outside version
control, then push them with the release entrypoint:
pnpm release:secrets --only api --file secrets.api.json
pnpm release:secrets --only gateway --file secrets.gateway.json
pnpm release:secrets --only mcp --file secrets.mcp.json
pnpm release:secrets --only otel --file secrets.otel.json
pnpm release:secrets --only telemetry-pipeline --file secrets.telemetry-pipeline.json
pnpm release:secrets --only diagnostics --file secrets.diagnostics.json
pnpm release:secrets --only maintenance --file secrets.maintenance.json
pnpm release:secrets --only telemetry-warehouse --file secrets.telemetry-warehouse.jsonScoping rules:
PROVON_R2_SQL_TOKENgoes only to telemetry readers;PROVON_R2_DATA_CATALOG_TOKENgoes only to the warehouse writer.- Identity-provider and Connector secrets belong only to their consuming Workers.
- The demo secret entrypoint rejects payment-provider and official-provider credential material; do not add those values to this deployment.
See Configuration for the full variable contract.
6. Validate And Deploy#
Run the Worker validation chain:
pnpm test:cfInspect telemetry maintenance configuration before applying it:
pnpm configure:cf:telemetry-maintenance
pnpm configure:cf:telemetry-maintenance:applyThe dry run lists the R2 lifecycle rules and Data Catalog settings it would configure:
OTLP and Gateway staging objects expire after 7 days by default; snapshot expiration keeps
at least a 15-day window for queue-replay idempotency and retains the last 10 snapshots;
compaction targets 64 MB files (allowed sizes 64, 128, 256, 512 MB). Applying requires
PROVON_R2_SQL_TOKEN or CLOUDFLARE_API_TOKEN.
Build, check, and publish the fixed artifacts:
pnpm release:build
pnpm release:check
pnpm release:publishPublishing uploads fixed artifacts only; it does not create resources or initialize D1. Prepare the current baseline schema explicitly before the first application release:
pnpm release:db-init --remoteThe project keeps only the current initialization baseline; development refactors do not
preserve old schema compatibility or migrate historical data. See the release workflow
reference in scripts/release/README.md.
7. Verify Public Request Endpoints#
curl --fail --silent https://api.provon.example/healthz
curl --fail --silent https://gateway.provon.example/healthz
curl --fail --silent https://mcp.provon.example/healthz
curl --fail --silent https://otel.provon.example/healthzRequest-facing Workers return JSON health; the pipeline, diagnostics, and maintenance
Workers return plain healthz: ok, and the warehouse Worker responds on /health.
End-to-end checks:
- Open the Workbench and sign in.
- Create a project API key through the API.
- Send OTLP to the OTLP origin and wait for the trace to become queryable through the API.
- Send a model request to the Gateway origin and confirm its provider-attempt trace.
- Confirm scheduled retention and maintenance task logs.
Note
A 2xx OTLP response means the payload was accepted and queued. It does not prove the
pipeline Worker, warehouse Container, Data Catalog, or R2 SQL read path completed.
Local Cloudflare Development#
Create .dev.vars from .dev.vars.example (PROVON_AUTH_SECRET and, when querying real telemetry,
PROVON_R2_SQL_TOKEN), then start the Workers:
pnpm dev:cfThis starts the API Worker as the primary Wrangler process with the OTLP, Gateway, MCP, pipeline, diagnostics, and maintenance Workers as auxiliary services. Start the Workbench separately:
pnpm dev:pagesUse per-Worker dev:worker:* scripts when isolating one Worker. Local emulation does not
replace a staging environment that exercises real Queues, R2 SQL, Data Catalog, Containers,
and Service Bindings.
Current Constraints#
- Telemetry reads require the Cloudflare R2 SQL backend.
- The default read model uses trace summaries and requires the summary queue on writer deployments.
- The warehouse Container and its Service Binding are required for Iceberg mutations.
- Cloudflare resource cost, service limits, regions, and recovery guarantees remain account-level operator responsibilities.