Skip to content
Cloudtifact docs

Self-hosting

Run Cloudtifact on your own Cloudflare account.

Cloudtifact runs on Cloudflare Workers: an API worker with D1 and R2, a content worker for published pages, a runtime worker for live apps, the web app (Next.js on OpenNext) and this site. The repository's README has the steps: create the D1 database and R2 bucket, add an environment to each wrangler.jsonc, set the secrets and deploy the API first.

Optional services

Each one is off until you set its secrets, and Cloudtifact works without it:

Secret (API worker)Without it
AI_API_KEYThe room AI is an offline assistant and builds use templates
CLERK_SECRET_KEYNo web sign-in (local development uses the dev login). Clerk handles sign-in only, not billing
AUTUMN_SECRET_KEYPlan limits come from the built-in plan table and upgrades are off

Billing with Autumn

All billing goes through Autumn on your own Stripe account. Clerk only handles sign-in, so leave Clerk Billing off. The plans and features are defined in code (packages/billing/autumn.config.ts, built from the plan table), so setting up an account is repeatable:

  1. Create an Autumn account and connect Stripe in test mode.
  2. Put AUTUMN_SECRET_KEY in your environment and run pnpm autumn:push, then --yes to apply.
  3. Set AUTUMN_SECRET_KEY on the API worker with wrangler secret put.
  4. Add a webhook in Autumn to <api>/v1/billing/webhook for billing.updated, and set its signing secret as AUTUMN_WEBHOOK_SECRET.

Invite emails

Invites are emailed through Cloudflare Email Service. Until it's set up, every invite shows a link to copy instead, so nothing breaks without it.

  1. Onboard your sending domain: npx wrangler email sending enable yourdomain.com.
  2. Set EMAIL_FROM in apps/api/wrangler.jsonc to an address on that domain, such as invites@yourdomain.com, and deploy the API.