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_KEY | The room AI is an offline assistant and builds use templates |
CLERK_SECRET_KEY | No web sign-in (local development uses the dev login). Clerk handles sign-in only, not billing |
AUTUMN_SECRET_KEY | Plan 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:
- Create an Autumn account and connect Stripe in test mode.
- Put
AUTUMN_SECRET_KEYin your environment and runpnpm autumn:push, then--yesto apply. - Set
AUTUMN_SECRET_KEYon the API worker withwrangler secret put. - Add a webhook in Autumn to
<api>/v1/billing/webhookforbilling.updated, and set its signing secret asAUTUMN_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.
- Onboard your sending domain:
npx wrangler email sending enable yourdomain.com. - Set
EMAIL_FROMinapps/api/wrangler.jsoncto an address on that domain, such asinvites@yourdomain.com, and deploy the API.