Skip to content
GitHub

Deployment Guide

Deploy Orion Kit’s three Next.js apps (web, app, api) to Vercel.

Deploy: apps/web (marketing), apps/app (dashboard), apps/api (backend)
Skip: apps/studio (local only), apps/docs (optional)
Order: API → App → Web (app needs API URL)

  1. GitHub repository with your Orion Kit code
  2. Vercel account (free plan is fine)
  3. Production API keys: Neon, Stripe, Resend, Axiom, PostHog

1. Neon (Database)

  • Create new project in Neon
  • Copy Pooled Connection URL
  • Run: export DATABASE_URL="postgresql://..." && pnpm db:push

2. Resend (Email)

  • Copy API key from Resend
  • Update FROM_EMAIL to your domain: hello@yourdomain.com

3. Stripe (Payments)

  • Toggle to Live Mode in Stripe
  • Create products → copy Price IDs
  • Get live API keys
  • Setup webhook AFTER deploying API

4. Axiom & PostHog

  • Create production dataset/project
  • Copy API tokens

1. Create Vercel Project

  • Go to Vercel Dashboard
  • Import GitHub repository
  • Root Directory: apps/apiIMPORTANT

2. Add Environment Variables

AUTH_JWT_SECRET=your-super-secret-key-min-32-chars
DATABASE_URL=postgresql://your-production-neon-url...
STRIPE_SECRET_KEY=sk_live_...
STRIPE_WEBHOOK_SECRET=whsec_...  # Update after webhook setup
STRIPE_PRICE_ID_PRO=price_...
STRIPE_PRICE_ID_ENTERPRISE=price_...
RESEND_API_KEY=re_...
FROM_EMAIL=hello@yourdomain.com
NEXT_PUBLIC_APP_URL=https://placeholder.vercel.app  # Update after app deploy
AXIOM_TOKEN=xaat-...
AXIOM_DATASET=orion-production

3. Deploy & Setup Webhook

  • Click Deploy → copy URL (e.g., https://orion-api-abc123.vercel.app)
  • In Stripe → WebhooksAdd Endpoint
  • URL: https://orion-api-abc123.vercel.app/webhooks/stripe
  • Events: checkout.session.completed, customer.subscription.*
  • Copy Signing Secret → update STRIPE_WEBHOOK_SECRET in Vercel → Redeploy

1. Create Vercel Project

  • Import same GitHub repo
  • Root Directory: apps/app

2. Add Environment Variables

DATABASE_URL=postgresql://your-production-neon-url...
NEXT_PUBLIC_API_URL=https://orion-api-abc123.vercel.app
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_live_...
STRIPE_PRICE_ID_PRO=price_...
STRIPE_PRICE_ID_ENTERPRISE=price_...
NEXT_PUBLIC_POSTHOG_KEY=phc_...
NEXT_PUBLIC_POSTHOG_HOST=https://us.i.posthog.com

3. Deploy & Update API

  • Click Deploy → copy URL (e.g., https://orion-app-xyz789.vercel.app)
  • In API project → Environment Variables → update NEXT_PUBLIC_APP_URL
  • Redeploy the API

1. Create Vercel Project

  • Import same GitHub repo
  • Root Directory: apps/web

2. Add Environment Variables

NEXT_PUBLIC_POSTHOG_KEY=phc_...
NEXT_PUBLIC_POSTHOG_HOST=https://us.i.posthog.com

3. Deploy

  • Click Deploy → copy URL (e.g., https://orion-web-def456.vercel.app)

1. Test signup flow:

  • Visit https://orion-app-xyz789.vercel.app
  • Sign up → should redirect to /dashboard

2. Test billing flow:

  • Go to /dashboard/billingUpgrade to Pro
  • Use test card: 4242 4242 4242 4242
  • Complete checkout → verify subscription in Stripe

3. Check services:

  • Axiom: Should see API logs
  • PostHog: Should see page views and events
  • Resend: Welcome emails sent on registration

1. Buy domain (e.g., yourdomain.com)

2. Add domains in Vercel:

  • Web: yourdomain.com, www.yourdomain.com
  • App: app.yourdomain.com
  • API: api.yourdomain.com

3. Update environment variables:

  • API: NEXT_PUBLIC_APP_URL=https://app.yourdomain.com
  • App: NEXT_PUBLIC_API_URL=https://api.yourdomain.com

4. Update Stripe webhook to https://api.yourdomain.com/webhooks/stripe

5. Redeploy all apps


API only accepts requests from your app domain for security.

  • apps/api/middleware.ts sets Access-Control-Allow-Origin to NEXT_PUBLIC_APP_URL
  • Prevents other websites from calling your API

Test: Try calling API from different domain → should get CORS error


IssueCauseFix
Build failsWrong root directorySet Root Directory to apps/api, apps/app, or apps/web
”DATABASE_URL not defined”Missing env varAdd DATABASE_URL in Vercel → Environment Variables → redeploy
”AUTH_JWT_SECRET not defined”Missing JWT secretAdd AUTH_JWT_SECRET with 32+ chars → redeploy
API 500 on webhookWrong Stripe webhook secretUpdate STRIPE_WEBHOOK_SECRET → redeploy
CORS errorWrong NEXT_PUBLIC_APP_URLUpdate to match actual app URL → redeploy
Email not sendingMissing Resend configAdd RESEND_API_KEY and FROM_EMAIL → redeploy

Common mistakes:

  • Wrong Root Directory in Vercel (defaults to repo root)
  • Using test keys instead of production keys
  • Not redeploying after updating environment variables

  • All 3 apps deployed (api, app, web)
  • Database schema pushed: pnpm db:push
  • Stripe webhook endpoint created
  • Resend API key configured
  • All environment variables set with production keys
  • Tested signup flow (create account → redirect to dashboard)
  • Tested billing flow (upgrade to Pro → payment → subscription active)
  • Logs appearing in Axiom
  • Analytics appearing in PostHog
  • CORS working (API only accepts requests from app domain)
  • Welcome emails sent on registration

Estimated time: ~45-60 minutes for first deployment