Skip to content
Browse documentation
On this page

Going to production

Set secrets, migrate the database, deploy the Worker and finish setup in the CMS and Stripe.

Once your resources are set up (see Cloudflare setup), going live takes a few commands.

  1. Set the secrets

    Run bunx wrangler secret put for BETTER_AUTH_SECRET, STRIPE_SECRET_KEY and STRIPE_WEBHOOK_SECRET.

  2. Migrate the database

    Run bun run db:migrate to apply the app migrations to the remote D1 database.

  3. Deploy

    Run bun run deploy. It builds with your PUBLIC_URL and uploads the Worker.

  4. Set up the CMS

    Open /_emdash/admin on your domain, create the admin account, then set the Site URL, title and logo in settings.

  5. Add the Stripe webhook

    Point a Stripe webhook at https://yourdomain.com/api/stripe/webhook for the customer.subscription.updated and customer.subscription.deleted events.

bunx wrangler secret put BETTER_AUTH_SECRET
bunx wrangler secret put STRIPE_SECRET_KEY
bunx wrangler secret put STRIPE_WEBHOOK_SECRET
bun run db:migrate
bun run deploy

Later deploys

  1. Apply any new migrations with bun run db:migrate before the code that needs them.
  2. Run bun run deploy.
  3. bunx wrangler deploy --dry-run shows the bindings and variables without deploying.

Logs

Observability is on in wrangler.jsonc. Stream live logs with bunx wrangler tail, or browse them in the Cloudflare dashboard.

Backups

D1 keeps point-in-time history with Time Travel (30 days on the paid plan, 7 on the free plan). Before a risky change, note the current bookmark so you can restore to it:

bunx wrangler d1 time-travel info my-app-cms

wrangler d1 export doesn't work on the CMS database because of its full-text search tables, so use Time Travel there. Media is in the R2 bucket.