vibecms.docs
Self-hosting

Self-host on Cloudflare

Operate the API, dashboard, and public blog on your own Cloudflare D1 and R2 resources.

Set:

SELF_HOSTED=true

Self-host mode disables hosted Polar gates and workspace API quotas while preserving scoped tokens, media safety limits, activity, and versions.

Topology

  1. The API and dashboard Worker (wrangler.jsonc) runs Hono, Better Auth, REST, MCP, media writes, and the static dashboard SPA.
  2. The OG Worker (wrangler.og.jsonc, name vibecms-og) renders share-card images.
  3. The public Worker (wrangler.public.jsonc) runs Astro SSR for blog pages, feeds, search, Markdown responses, and media reads. It reaches the API through the API service binding and the OG Worker through the OG service binding pointing at vibecms-og.
  4. The API and public Workers share one D1 database and one R2 bucket. The OG Worker binds neither; the public Worker reaches it only through the OG service binding.

Required secrets

pnpm --filter @vc/api exec wrangler secret put BETTER_AUTH_SECRET --config ../../wrangler.jsonc
pnpm --filter @vc/api exec wrangler secret put TOKEN_PEPPER --config ../../wrangler.jsonc

Generate each value with:

openssl rand -hex 32

Production OTP delivery also requires a configured EMAIL binding and sender domain.

Scheduled jobs

The API Worker’s wrangler.jsonc declares three cron triggers — three of the five a Workers Free account allows: 17 2 * * * runs the daily analytics rollup and the subpath location re-check, */15 * * * * runs media reconciliation, and * * * * * publishes due scheduled posts. Removing the daily trigger stops history rollups and location re-checks; scheduled publishing depends on the every-minute trigger.

Optional analytics and AI

Blog analytics turn on when the public Worker has an analytics_engine_datasets binding named ANALYTICS and both Workers set ANALYTICS_ACCOUNT_ID, ANALYTICS_DATASET, and ANALYTICS_API_TOKEN (see docs/self-hosting.md). Without them, analytics collects nothing.

AI SEO reviews need a Workers AI binding named AI on the API Worker; SEO_REVIEW_MODEL picks the model. Without the binding, AI review requests return AI_UNAVAILABLE and deterministic SEO checks still work.

Deploy

After replacing the placeholder resource IDs, names, service target, and hosts in the root Wrangler files:

pnpm install
pnpm typecheck
pnpm test
pnpm build:self-host
pnpm deploy

pnpm deploy builds all three Workers, applies D1 migrations, then deploys them in order: API, OG, public. The public Worker’s OG service binding targets the OG Worker by name (vibecms-og by default) — keep that name in sync if you rename it in wrangler.og.jsonc.

For the full operator contract, resource list, email setup, and deployment caveats, see docs/self-hosting.md.