Deployment Guide
This guide covers deploying your SaaS to production.
Vercel Deployment (Recommended)
One-Click Deploy
Manual Deployment
- Push your code to GitHub
- Go to vercel.com and sign in
- Click Add New > Project
- Import your repository
- Configure environment variables (see below)
- Click Deploy
Environment Variables
Add these in Vercel project settings > Environment Variables:
# Supabase
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
SUPABASE_SERVICE_ROLE_KEY=your-service-role-key
# Stripe (use live keys for production!)
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_live_...
STRIPE_SECRET_KEY=sk_live_...
STRIPE_WEBHOOK_SECRET=whsec_...
NEXT_PUBLIC_STRIPE_PRICE_ID_FREE=price_...
NEXT_PUBLIC_STRIPE_PRICE_ID_PRO_MONTHLY=price_...
NEXT_PUBLIC_STRIPE_PRICE_ID_PRO_YEARLY=price_...
NEXT_PUBLIC_STRIPE_PRICE_ID_ENTERPRISE_MONTHLY=price_...
NEXT_PUBLIC_STRIPE_PRICE_ID_ENTERPRISE_YEARLY=price_...
# Resend
RESEND_API_KEY=re_...
EMAIL_FROM=YourApp <noreply@yourdomain.com>
EMAIL_REPLY_TO=support@yourdomain.com
# App URL (your production domain)
NEXT_PUBLIC_APP_URL=https://yourdomain.com
Custom Domain Setup
In Vercel
- Go to your project > Settings > Domains
- Add your domain (e.g.,
yourdomain.com) - Follow instructions to update DNS records
- Wait for SSL certificate provisioning
DNS Configuration
Add these records at your DNS provider:
| Type | Name | Value | |------|------|-------| | A | @ | 76.76.21.21 | | CNAME | www | cname.vercel-dns.com |
Production Checklist
Supabase
- [ ] Update Site URL in Auth settings to your production domain
- [ ] Add production domain to Redirect URLs
- [ ] Review and tighten RLS policies
- [ ] Enable database backups
- [ ] Consider upgrading to a paid plan for production workloads
Stripe
- [ ] Create products and prices in live mode
- [ ] Update to live API keys
- [ ] Set up production webhook endpoint:
- URL:
https://yourdomain.com/api/stripe/webhooks - Events:
checkout.session.completed,customer.subscription.*,invoice.*
- URL:
- [ ] Configure customer portal return URL
- [ ] Test with a real card (small amount, then refund)
Resend
- [ ] Verify your production domain
- [ ] Update
EMAIL_FROMto use your domain - [ ] Test email delivery
- [ ] Consider upgrading plan for higher volume
Google OAuth (if using)
- Go to Google Cloud Console
- Update OAuth credentials:
- Add production redirect URI:
https://your-project.supabase.co/auth/v1/callback - Update authorized JavaScript origins
- Add production redirect URI:
- Submit for verification if needed
Security
- [ ] Ensure all secrets are in environment variables (not in code)
- [ ] Enable 2FA on all service accounts
- [ ] Review CORS settings in Supabase
- [ ] Set up error monitoring (e.g., Sentry)
- [ ] Configure rate limiting if needed
Post-Deployment
Verify Everything Works
- Sign up with email and password
- Sign up with Google OAuth
- Subscribe to a paid plan
- Manage subscription through customer portal
- Receive emails (welcome, subscription confirmation)
- Check webhooks are processing correctly
Monitor
- Set up Vercel Analytics
- Monitor Stripe webhook events
- Check Resend delivery stats
- Set up error alerting
Scaling Considerations
Database
- Use Supabase connection pooling
- Add indexes for frequently queried columns
- Consider read replicas for heavy read loads
Caching
- Use Vercel Edge Config for feature flags
- Implement Redis for session/data caching
- Use ISR for blog pages
CDN
Vercel automatically serves your app from the edge, but consider:
- Image optimization with
next/image - Static asset caching headers
- API route caching where appropriate
Rollback
If something goes wrong:
- Vercel: Click on a previous deployment > Promote to Production
- Database: Restore from Supabase backups
- Stripe: Use test mode to debug, then re-deploy
Environment-Specific Builds
For different configurations per environment:
// next.config.js
module.exports = {
env: {
ENVIRONMENT: process.env.VERCEL_ENV || 'development',
},
};
// In your code
if (process.env.ENVIRONMENT === 'production') {
// Production-only code
}
Troubleshooting
Build Fails
- Check build logs in Vercel
- Ensure all env vars are set
- Run
npm run buildlocally to debug
Webhooks Not Working
- Verify webhook URL is correct
- Check webhook signing secret
- View webhook logs in Stripe Dashboard
OAuth Redirect Errors
- Verify redirect URLs in Supabase and Google
- Check Site URL in Supabase matches your domain
- Ensure SSL is working (no mixed content)
Database Connection Issues
- Check Supabase project is running
- Verify connection string
- Check RLS policies aren't blocking access