Deployment
Deploy your Next.js starter kit to production
Deployment
Deploy your application to production with this comprehensive guide.
Pre-Deployment Checklist
Before deploying, ensure you have:
Database
- Production database ready (Neon, Supabase, etc.)
- Database backups configured
- Connection pooling enabled
- SSL connections configured
Environment Variables
- All required env vars set
- Production secrets generated
- API keys for production services
-
NODE_ENV=production
Services
- Stripe live keys configured
- Email provider production account
- UploadThing production token
- OAuth apps configured for production URLs
Code
- All tests passing
- Build succeeds locally
- No console.log statements
- Error handling implemented
- Rate limiting configured
Security
- Security headers enabled
- HTTPS enforced
- Secrets rotated from development
- Admin accounts secured
Deployment Options
Vercel (Recommended)
Vercel is the easiest option for Next.js applications.
1. Install Vercel CLI
npm i -g vercel2. Login
vercel login3. Deploy
# From project root
cd nextjs-starter-kit
vercelFollow prompts to link project.
4. Set Environment Variables
Option A: Vercel CLI
vercel env add BETTER_AUTH_SECRET
# Paste value when prompted
vercel env add DATABASE_URL
vercel env add STRIPE_SECRET_KEY
# ... add all env varsOption B: Vercel Dashboard
- Go to project settings
- Navigate to Environment Variables
- Add each variable
- Select environments (Production, Preview, Development)
5. Deploy to Production
vercel --prodYour app will be live at https://your-project.vercel.app!
6. Custom Domain
- Go to project settings > Domains
- Add your custom domain
- Configure DNS records
- Update
BETTER_AUTH_URLandNEXT_PUBLIC_APP_URL
vercel env add BETTER_AUTH_URL production
# Enter: https://yourdomain.com
vercel env add NEXT_PUBLIC_APP_URL production
# Enter: https://yourdomain.comOther Platforms
The app can also be deployed to:
Railway
# Install Railway CLI
npm i -g @railway/cli
# Login
railway login
# Initialize project
railway init
# Add env vars in Railway dashboard
# Deploy
railway upNetlify
# Install Netlify CLI
npm i -g netlify-cli
# Login
netlify login
# Deploy
netlify deploy --prodDocker
# Dockerfile
FROM node:20-alpine AS base
# Install dependencies only when needed
FROM base AS deps
RUN apk add --no-cache libc6-compat
WORKDIR /app
COPY package.json pnpm-lock.yaml ./
RUN corepack enable pnpm && pnpm i --frozen-lockfile
# Build the app
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN corepack enable pnpm && pnpm build
# Production image
FROM base AS runner
WORKDIR /app
ENV NODE_ENV production
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
COPY --from=builder /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
USER nextjs
EXPOSE 3000
ENV PORT 3000
CMD ["node", "server.js"]# Build
docker build -t nextjs-starter .
# Run
docker run -p 3000:3000 --env-file .env nextjs-starterDatabase Migration
Neon (Recommended)
- Create production database at neon.tech
- Copy connection string
- Add to Vercel env vars
vercel env add DATABASE_URL production
# Paste Neon connection string- Push schema
# Set DB URL temporarily for migration
export DATABASE_URL="your-production-db-url"
pnpm db:pushSupabase
- Create project at supabase.com
- Get connection string from Settings > Database
- Add to environment variables
- Run migrations
Stripe Configuration
1. Switch to Live Mode
In Stripe Dashboard, toggle to "Live mode".
2. Update API Keys
vercel env add STRIPE_SECRET_KEY production
# Enter live secret key (sk_live_...)
vercel env add STRIPE_PUBLISHABLE_KEY production
# Enter live publishable key (pk_live_...)3. Create Products & Prices
Create products in live mode with same structure as test mode.
4. Update Price IDs
vercel env add STRIPE_PRICE_PRO_MONTHLY production
vercel env add STRIPE_PRICE_PRO_YEARLY production
vercel env add STRIPE_PRICE_STARTUP_MONTHLY production
vercel env add STRIPE_PRICE_STARTUP_YEARLY production5. Configure Webhook
- Go to Developers > Webhooks
- Add endpoint:
https://yourdomain.com/api/stripe/webhook - Select all subscription and invoice events
- Copy signing secret
vercel env add STRIPE_WEBHOOK_SECRET production
# Paste webhook secretEmail Configuration
Resend (Recommended for Production)
- Verify your domain at resend.com
- Get production API key
- Configure:
vercel env add EMAIL_PROVIDER production
# Enter: resend
vercel env add RESEND_API_KEY production
# Enter API key
vercel env add EMAIL_FROM production
# Enter: Your App <noreply@yourdomain.com>Other Providers
Configure similarly with production credentials.
OAuth Configuration
Google OAuth
- Go to Google Cloud Console
- Update OAuth consent screen
- Add authorized redirect URI:
https://yourdomain.com/api/auth/callback/google
- Get production credentials
- Add to Vercel:
vercel env add GOOGLE_CLIENT_ID production
vercel env add GOOGLE_CLIENT_SECRET productionGitHub OAuth
- Go to GitHub OAuth Apps
- Create new app or update existing
- Set callback URL:
https://yourdomain.com/api/auth/callback/github - Add credentials to Vercel
Post-Deployment Steps
1. Verify Deployment
Check your deployed app:
- ✅ Homepage loads
- ✅ Sign up works
- ✅ Sign in works
- ✅ OAuth works
- ✅ Email sending works
- ✅ Blog posts display
- ✅ Admin dashboard accessible
2. Create Admin Account
- Sign up with your admin email
- SSH into server or use Vercel CLI
# Run admin setup script
vercel env pull # Get env vars locally
pnpm admin:setupOr manually update user role in database.
3. Seed Production Data
# Run setup script
pnpm project:setup
# Or individually
pnpm plans:setup
pnpm blog:seed
pnpm testimonials:seed4. Test Critical Flows
- Authentication: Sign up, sign in, password reset
- Subscriptions: Create test subscription
- Webhooks: Verify Stripe webhooks work
- Emails: Send test emails
- File Uploads: Upload test files
5. Monitor
Set up monitoring:
- Vercel Analytics
- Sentry for error tracking
- Uptime monitoring (UptimeRobot, Pingdom)
- Log aggregation (LogDNA, Datadog)
Security Headers
Verify security headers are enabled in production:
curl -I https://yourdomain.comShould include:
Strict-Transport-Security: max-age=31536000
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Content-Security-Policy: ...Performance Optimization
Enable Edge Caching
Configure Next.js to use edge caching:
// app/blog/page.tsx
export const revalidate = 3600; // Revalidate every hourImage Optimization
Images are auto-optimized by Next.js Image component.
CDN
Vercel automatically uses CDN for static assets.
Database Connection Pooling
Enable connection pooling in database settings for better performance.
Monitoring & Maintenance
Logs
View logs in Vercel Dashboard > Functions > Logs.
Error Tracking
Install Sentry:
pnpm add @sentry/nextjs// sentry.client.config.ts
import * as Sentry from "@sentry/nextjs";
Sentry.init({
dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
tracesSampleRate: 1.0,
});Uptime Monitoring
Set up alerts for downtime:
- UptimeRobot (free)
- Pingdom
- Vercel built-in monitoring
Backup Strategy
- Database: Daily automated backups (Neon/Supabase)
- User uploads: S3/R2 with versioning
- Code: Git repository
- Environment vars: Secure vault
Rollback Strategy
Vercel
- Go to Deployments
- Find working deployment
- Click "..." > Promote to Production
Manual
# Revert to previous commit
git revert HEAD
git push
# Or
git reset --hard <commit-hash>
git push --forceScaling
Database
- Upgrade Neon/Supabase plan
- Enable connection pooling
- Add read replicas
- Index frequently queried columns
Application
Vercel auto-scales. For other platforms:
- Horizontal scaling (multiple instances)
- Load balancer
- Cache frequently accessed data
File Storage
- Use CDN for uploads
- Implement lazy loading
- Compress images
Cost Optimization
Vercel
- Free tier: Hobby projects
- Pro ($20/month): Small apps
- Enterprise: Large apps
Database
- Neon: Free tier available, pay as you grow
- Supabase: Free tier, then $25/month
Other Services
- Resend: 100 emails/day free
- UploadThing: 2GB free
- OpenRouter: Free models available
Troubleshooting
Build Failures
Check build logs in Vercel dashboard. Common issues:
- Missing environment variables
- TypeScript errors
- Dependency issues
Database Connection Errors
- Verify connection string
- Check database is running
- Ensure IP allowlist includes Vercel IPs
- Enable SSL
Webhook Issues
- Verify endpoint is accessible (HTTPS)
- Check webhook secret matches
- Review Stripe webhook logs
Email Not Sending
- Verify domain is verified with provider
- Check API keys are correct
- Review email logs in provider dashboard
Best Practices
- Use Environment Variables - Never hardcode secrets
- Enable HTTPS - Always use secure connections
- Monitor Errors - Set up error tracking
- Regular Backups - Automate database backups
- Update Dependencies - Keep packages up-to-date
- Test Before Deploy - Run tests in CI/CD
- Gradual Rollout - Use preview deployments
- Document Changes - Keep changelog updated
CI/CD Pipeline
GitHub Actions
# .github/workflows/deploy.yml
name: Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: "20"
- uses: pnpm/action-setup@v2
- name: Install dependencies
run: pnpm install
- name: Run tests
run: pnpm test
- name: Build
run: pnpm build
- name: Deploy to Vercel
run: vercel --prod --token=${{ secrets.VERCEL_TOKEN }}