Production Environment Variables
All five environment variables are required for production. Unlike development, you must not use test or development credentials in production.Complete Configuration
.env
Environment Variable Details
BASE_URL
Purpose: Your production domain, used for redirects and webhooks
Production Value: https://yourdomain.com
Notes:
- Must include protocol (
https://) - No trailing slash
- Must match your actual domain
- Used by authentication redirects and Stripe checkout
POSTGRES_URL
Purpose: Connection string for your production PostgreSQL database
Format: postgresql://[user]:[password]@[host]:[port]/[database]?[params]
Example:
- Always use SSL/TLS in production (
?sslmode=require) - Use connection pooling for serverless environments
- Restrict database user permissions (no DROP, CREATE on production)
- Use strong, unique passwords
STRIPE_SECRET_KEY
Purpose: Authenticates requests to Stripe API
Production Value: sk_live_... (not sk_test_...)
Where to Find:
- Go to dashboard.stripe.com/apikeys
- Toggle Viewing test data to OFF (production mode)
- Copy the Secret key
- Never log or expose this key
- Rotate keys if compromised
- Used in
lib/payments/stripe.tsto initialize Stripe SDK
STRIPE_WEBHOOK_SECRET
Purpose: Verifies webhook requests are from Stripe
Production Value: whsec_...
How to Get: See Stripe Production Webhook Setup below
Security Notes:
- Each webhook endpoint has a unique signing secret
- Used for signature verification in
app/api/stripe/webhook/route.ts:5-20 - Production and test webhooks have different secrets
AUTH_SECRET
Purpose: Secret key for signing and verifying JWT authentication tokens
Production Value: 32+ character random string
Generate Securely:
- Used by
lib/auth/session.tsto sign JWTs - Protects against token forgery
- Critical for authentication security
Stripe Production Webhook Setup
Production webhooks are essential for handling subscription lifecycle events.Step-by-Step Configuration
Navigate to Stripe Dashboard
- Go to dashboard.stripe.com
- Switch to production mode (toggle in top right should be OFF)
- Navigate to Developers → Webhooks
Create Webhook Endpoint
Click Add endpoint and configure:Endpoint URL:
https://yourdomain.com/api/stripe/webhookThis URL must match your production domain. The route is implemented in
app/api/stripe/webhook/route.ts.Select Events
Add the following events that your application listens for:
- ✅
customer.subscription.updated - ✅
customer.subscription.deleted
handleSubscriptionChange() in lib/payments/stripe.ts.Copy Signing Secret
After creating the endpoint:
- Click on your new webhook endpoint
- Click Reveal next to Signing secret
- Copy the secret (starts with
whsec_...) - Add to your environment variables as
STRIPE_WEBHOOK_SECRET
Webhook Implementation
The webhook handler inapp/api/stripe/webhook/route.ts performs:
- Signature Verification (line 14): Validates request is from Stripe
- Event Processing (lines 23-31): Handles subscription updates/deletions
- Database Updates: Calls
handleSubscriptionChange()to update user subscriptions
Monitoring Webhooks
Monitor webhook delivery in Stripe Dashboard:- Go to Developers → Webhooks
- Click on your endpoint
- View Recent deliveries to see success/failure status
{"received": true}
Common Failures:
- 400 Bad Request: Signature verification failed (check
STRIPE_WEBHOOK_SECRET) - 500 Internal Server Error: Application error (check logs)
- Timeout: Request took >5 seconds (optimize webhook handler)
Security Considerations
Production deployments require additional security measures.Authentication Security
The application uses JWT-based authentication with several security features:Session Management
Implementation:middleware.ts:18-41
httpOnly: Cookies inaccessible to JavaScript (XSS protection)secure: Only transmitted over HTTPSsameSite: 'lax': Prevents CSRF attacks- 24-hour expiration with automatic renewal
Route Protection
Global Middleware:middleware.ts:5-14
/dashboard require authentication.
Password Security
Passwords are hashed using bcrypt with automatic salting:- Implemented in authentication actions
- Never store plaintext passwords
- Hash strength is automatically managed by bcrypt
API Security
All API routes should validate authentication:Environment Security
Secrets Management
Secrets Management
Never commit secrets to version control:
- Add
.envto.gitignore - Use platform environment variables (Vercel, AWS, etc.)
- Rotate secrets if exposed
- Use different secrets per environment
HTTPS/SSL
HTTPS/SSL
Always use HTTPS in production:
- Vercel provides automatic SSL certificates
- Enforce HTTPS for all requests
- Check
secure: truein cookie configuration - Use
sslmode=requirefor database connections
Database Security
Database Security
Protect your production database:
- Use strong passwords (20+ random characters)
- Enable SSL/TLS for connections
- Restrict IP access if possible
- Use least-privilege database users
- Regular backups and disaster recovery plan
- Monitor for suspicious queries
Dependency Security
Dependency Security
Keep dependencies updated:Set up automated security alerts:
- Enable Dependabot on GitHub
- Monitor npm advisories
- Test updates before deploying
Database Considerations
Production database setup requires careful planning.Connection Pooling
Why Needed: Serverless functions create new connections per request Solutions:- Vercel Postgres: Built-in connection pooling
- Neon: Serverless-native with automatic pooling
- Supabase: Use connection pooling port (6543)
- PgBouncer: Self-hosted connection pooler
Migrations
Run migrations using Drizzle Kit:Database Schema
The application schema is defined inlib/db/schema.ts with tables for:
users- User accounts and authenticationteams- Team/workspace managementteamMembers- User-team relationships with RBACactivityLogs- Audit trail of user actions
Backups
Automated Backups:- Vercel Postgres: Automatic daily backups (retained 7 days)
- Neon: Point-in-time recovery (configurable retention)
- Supabase: Daily backups (configurable retention)
Monitoring
Monitor database health:- Connection count: Ensure not hitting limits
- Query performance: Identify slow queries
- Storage usage: Plan for scaling
- Error rates: Catch issues early
Production Checklist
Before going live, verify all items:Environment Variables
Environment Variables
- ✅
BASE_URLset to production domain - ✅
POSTGRES_URLpoints to production database with SSL - ✅
STRIPE_SECRET_KEYis production key (sk_live_...) - ✅
STRIPE_WEBHOOK_SECRETfrom production webhook - ✅
AUTH_SECRETis cryptographically random - ✅ No test or development values in production
Stripe Configuration
Stripe Configuration
- ✅ Using production API keys
- ✅ Production webhook created
- ✅ Webhook events configured (subscription.updated, subscription.deleted)
- ✅ Webhook secret added to environment variables
- ✅ Test webhook receives 200 OK response
- ✅ Webhook URL matches production domain
Database
Database
- ✅ Production database created
- ✅ Migrations applied
- ✅ SSL/TLS enabled
- ✅ Connection pooling configured
- ✅ Automated backups enabled
- ✅ Database credentials are secure
Security
Security
- ✅ HTTPS enabled (automatic with Vercel)
- ✅ Secure cookie settings verified
- ✅ Authentication middleware active
- ✅ No secrets in source control
- ✅ Dependencies updated and audited
- ✅ Error handling doesn’t expose sensitive info
Testing
Testing
- ✅ Production build succeeds (
pnpm build) - ✅ Authentication flow works
- ✅ Stripe checkout completes successfully
- ✅ Webhooks process correctly
- ✅ Protected routes require authentication
- ✅ Database operations work correctly
Going Live
Once all checklist items are complete:Final Testing
Test critical user flows:
- Sign up new account
- Complete payment (use real card, then refund)
- Access dashboard
- Manage subscription via customer portal
Monitor Initial Traffic
Watch logs and metrics closely:
- Check for errors in deployment logs
- Monitor webhook delivery success rate
- Verify database connections are stable
- Watch for authentication issues
Consider a soft launch with limited users before full public release to catch any production-specific issues.
Support and Maintenance
Regular Maintenance
- Weekly: Review error logs and webhook delivery
- Monthly: Update dependencies, review security advisories
- Quarterly: Database performance review, backup restoration test
Getting Help
- GitHub Issues: github.com/nextjs/saas-starter/issues
- Next.js Docs: nextjs.org/docs
- Stripe Support: support.stripe.com
- Vercel Support: vercel.com/support
Deploy to Vercel
Ready to deploy? Follow our step-by-step Vercel deployment guide