BunshipBunship
Getting Started

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 32

Use 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:

2. Vercel Deployment (TurboRepo)

Because this repo is TurboRepo-based, there are two valid setups.

Use the repository root as Vercel Root Directory.

Vercel fieldValue
Framework PresetNext.js
Root Directory. (repo root)
Install Commandbun install
Build Commandbunx turbo run build --filter=@bunship-ai/ship...
Output Directoryempty (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 fieldValue
Framework PresetNext.js
Root Directoryapps/ship
Include files outside root directory in Build StepEnabled
Install Commandbun install
Build Commandbun run build
Output Directoryempty (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:

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 deploy

bun run deploy executes:

  1. opennextjs-cloudflare build
  2. opennextjs-cloudflare deploy

Cloudflare references:

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