Deployment
Deploy to Vercel, Docker, or Railway. Includes Docker local dev setup and production container build.
Vercel (Recommended)
Push to GitHub
git push origin mainImport in Vercel
Go to vercel.com/new → Import your repository.
Add environment variables
Add every variable from .env.example. The required ones are:
DATABASE_URL="postgresql://..."
AUTH_SECRET="your-32-byte-secret" # openssl rand -base64 32
NEXTAUTH_URL="https://yourdomain.com"All other env vars (payment providers, email, feature flags, etc.) should also be added.
Deploy
Click Deploy. Vercel runs pnpm build automatically.
Configure webhooks
After deploy, update webhook URLs in your payment dashboards:
- LemonSqueezy: Settings → Webhooks →
https://yourdomain.com/api/webhooks/lemonsqueezy - Polar: Settings → Webhooks →
https://yourdomain.com/api/webhooks/polar - Stripe: Dashboard → Developers → Webhooks →
https://yourdomain.com/api/webhooks/stripe
Run database migration
Run from your local machine (pointing at production DB):
DATABASE_URL="your-production-db-url" pnpm db:pushOr use prisma migrate deploy if you have migration history.
Create your SuperAdmin account
DATABASE_URL="your-production-db-url" pnpm make-superadmin your@email.comLocal Development with Docker
Use Docker to run PostgreSQL locally without installing it on your machine.
# Start PostgreSQL (postgres:17-alpine on port 5432)
pnpm docker:dev
# Set DATABASE_URL in .env.local
DATABASE_URL="postgresql://launchfst:launchfst@localhost:5432/launchfst"
# Push schema
pnpm db:push
# Start dev server
pnpm dev
# Stop PostgreSQL when done
pnpm docker:downDocker Compose credentials: user launchfst, password launchfst, database launchfst.
Docker Production Build
The included Dockerfile uses a multi-stage build on node:22-alpine:
- deps — install dependencies with
pnpm install --frozen-lockfile - builder — generate Prisma client and run
pnpm build - runner — minimal production image with
next start
# Build the image
docker build -t yoursaas:latest .
# Run the container
docker run -p 3000:3000 \
-e DATABASE_URL="postgresql://..." \
-e AUTH_SECRET="..." \
-e NEXTAUTH_URL="https://yourdomain.com" \
yoursaas:latestOr use the production Docker Compose file:
pnpm docker:build # docker compose -f docker-compose.prod.yml build
pnpm docker:prod # docker compose -f docker-compose.prod.yml up -dRailway
Create a new project
Go to railway.app → New Project → Deploy from GitHub repo.
Add a PostgreSQL service
Click "+ New" → Database → PostgreSQL. Railway injects DATABASE_URL automatically.
Add environment variables
In Railway → your service → Variables, add all required env vars from .env.example.
Deploy
Railway auto-deploys on every push to your default branch.
Available Scripts
| Command | Description |
|---|---|
pnpm dev | Start Next.js dev server with Turbopack |
pnpm build | Production build |
pnpm start | Start production server |
pnpm lint | Run ESLint |
pnpm db:push | Push Prisma schema to database |
pnpm db:generate | Regenerate Prisma client |
pnpm db:studio | Open Prisma Studio |
pnpm make-superadmin | Promote a user to SUPERADMIN |
pnpm seed-demo | Seed demo users and org |
pnpm email:preview | Start React Email preview server (port 3001) |
pnpm docker:dev | Start local PostgreSQL via Docker Compose |
pnpm docker:down | Stop local Docker Compose services |
pnpm docker:build | Build production Docker image |
pnpm docker:prod | Run production Docker Compose |
Post-Deploy Checklist
-
NEXTAUTH_URLis set to the production domain (not localhost) -
AUTH_SECRETis a secure random string (32+ bytes) -
DATABASE_URLpoints to the production database - Prisma schema is pushed:
pnpm db:push - SuperAdmin account created:
pnpm make-superadmin your@email.com - Payment webhook URLs updated in provider dashboards
- Email provider configured and domain verified
- Feature flags set correctly for production