Deployment
Copy-paste deployment guide for Bunship on Vercel and Cloudflare (TurboRepo).
Deployment Model
Bunship is a TurboRepo monorepo.
Production is deployed as one site (apps/ship) that serves:
- Marketing pages
- App workspace
- Admin pages
- Docs routes and docs search API
- API routes under
/api/v1/*
No separate docs deployment is required.
1. Required Env Vars (Copy First)
Generate a secret first:
openssl rand -base64 32Use this as a baseline production env set:
# Core auth + app URLs
BETTER_AUTH_SECRET="replace-with-long-random-secret"
AUTH_SECRET="replace-with-long-random-secret"
BETTER_AUTH_URL="https://YOUR_DOMAIN"
NEXT_PUBLIC_SITE_URL="https://YOUR_DOMAIN"
NEXT_PUBLIC_SERVER_URL="https://YOUR_DOMAIN"
NEXT_PUBLIC_API_PREFIX="/api/v1"
ADMIN_EMAIL_LIST="admin@YOUR_DOMAIN"
EMAIL_FROM="Bunship <noreply@YOUR_DOMAIN>"
# OAuth
OAUTH_GITHUB_CLIENT_ID="xxx"
OAUTH_GITHUB_CLIENT_SECRET="xxx"
OAUTH_GOOGLE_CLIENT_ID="xxx"
OAUTH_GOOGLE_CLIENT_SECRET="xxx"
NEXT_PUBLIC_OAUTH_GOOGLE_CLIENT_ID="xxx"
# Database + mail
DATABASE_URL="postgresql://..."
RESEND_API_KEY="re_xxx"
# Stripe
STRIPE_SECRET_KEY="sk_live_xxx"
STRIPE_WEBHOOK_SECRET="whsec_xxx"
# Storage (S3-compatible / R2)
S3_ENDPOINT="https://<account>.r2.cloudflarestorage.com"
S3_REGION="auto"
S3_ACCESS_KEY="xxx"
S3_SECRET_KEY="xxx"
S3_BUCKET="your-bucket"
NEXT_PUBLIC_S3_URL_BASE="https://cdn.YOUR_DOMAIN"
# Misc required by current validators
S_GITHUB_PERSONAL_ACCESS_TOKEN="ghp_xxx"
CLOUDFLARE_ACCOUNT_ID="xxx"If you use Better Auth, set both AUTH_SECRET and BETTER_AUTH_SECRET (keeping them identical is fine). If you use Clerk, provide NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY, CLERK_SECRET_KEY, and CLERK_WEBHOOK_SECRET instead.
Setup references:
- Better Auth docs: https://www.better-auth.com/docs/introduction
- Clerk docs: https://clerk.com/docs
- GitHub OAuth app: https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/creating-an-oauth-app
- Google OAuth: https://developers.google.com/identity/protocols/oauth2
- Stripe keys + webhook: https://docs.stripe.com/keys, https://docs.stripe.com/webhooks
- Resend API keys: https://resend.com/docs
- Full env list in this repo: /en/docs/operations/env-config
2. Vercel Deployment (TurboRepo)
Because this repo is TurboRepo-based, there are two valid setups.
Option A (Recommended): Turbo Root Mode
Use the repository root as Vercel Root Directory.
| Vercel field | Value |
|---|---|
| Framework Preset | Next.js |
| Root Directory | . (repo root) |
| Install Command | bun install |
| Build Command | bunx turbo run build --filter=@bunship-ai/ship... |
| Output Directory | empty (Next.js default) |
Why this mode: clearer monorepo behavior, better with Turbo dependency graph and cache.
Option B: App Root Mode
If you keep Root Directory = apps/ship, use:
| Vercel field | Value |
|---|---|
| Framework Preset | Next.js |
| Root Directory | apps/ship |
| Include files outside root directory in Build Step | Enabled |
| Install Command | bun install |
| Build Command | bun run build |
| Output Directory | empty (Next.js default) |
In App Root Mode, keep “Include files outside root directory in Build Step” enabled, otherwise workspace packages may not resolve.
After deploy, configure Stripe webhook endpoint:
https://YOUR_DOMAIN/api/v1/webhook/stripe
Vercel references:
- Monorepo guide: https://vercel.com/docs/monorepos
- Build settings: https://vercel.com/docs/builds/configure-a-build
- Turbo filtering: https://turbo.build/repo/docs/crafting-your-repository/running-tasks#using-filters
3. Cloudflare Deployment (OpenNext)
This repo already includes OpenNext Cloudflare config (apps/ship/open-next.config.ts + apps/ship/wrangler.jsonc).
Run from repo root:
bun install
cd apps/ship
bunx wrangler login
bun run deploybun run deploy executes:
opennextjs-cloudflare buildopennextjs-cloudflare deploy
Cloudflare references:
- OpenNext Cloudflare docs: https://opennext.js.org/cloudflare
- Wrangler config: https://developers.cloudflare.com/workers/wrangler/configuration/
- Secrets/variables: https://developers.cloudflare.com/workers/configuration/secrets/
If you deploy on Cloudflare, set VERCEL_ENV=production in runtime variables to match production behavior expected by parts of this template.
4. One-Click Deployment Checklist
Vercel
- Import Git repo
- Choose Option A or Option B settings above
- Add required env vars
- Deploy
- Add Stripe webhook endpoint
- Run smoke tests below
Cloudflare
- Create/choose Workers project
- Add required env vars/secrets
-
bun install -
cd apps/ship && bun run deploy - Bind custom domain
- Run smoke tests below
5. Post-Deploy Smoke Test
-
/:locale/docs -
/:locale/signin -
/:locale/subscription -
/:locale/admin -
/api/v1/health(if enabled) -
/api/docs/search