Deployment
Deploy Unstack Pro to production
Deployment
Deploy to production in minutes. Auth is already configured just set your production environment variables and go live.
No auth configuration needed for deployment. Just connect services with production credentials.
Prerequisites
Before deploying, ensure you have:
- Completed local development setup
- Convex account and project
- Resend account for email sending
- Autumn account for billing
- Vercel account (free tier works)
- Domain name (optional but recommended)
- All environment variables documented
Deployment Steps
Prepare Your Repository
-
Commit all changes:
git add . git commit -m "Ready for deployment" -
Push to GitHub:
git push origin main -
Verify
.gitignoreincludes:.env.local.envnode_modules/.next/
Configure Convex for Production
-
Go to your Convex dashboard: dashboard.convex.dev
-
Create production deployment:
- Click your project
- Go to "Settings"
- Note your production deployment name
-
Set production environment variables:
- Copy your entire .env file
- Go to "Settings" > "Environment Variables" tab
- Paste variables, updating:
CONVEX_DEPLOYMENTtoprod:your-deployment-nameNEXT_PUBLIC_CONVEX_URLandNEXT_PUBLIC_CONVEX_SITE_URLto production URLsNEXT_PUBLIC_APP_URLto your production domain
-
Save changes
Use different secrets for production! Never reuse development secrets.
Deploy to Vercel
-
Go to vercel.com
-
Import your repository:
- Click "New Project"
- Import from GitHub
- Select your repository
-
Configure project:
- Framework Preset: Next.js
- Root Directory:
./ - Build Command:
next build - Output Directory:
.next
-
Add environment variables:
Go to "Environment Variables" and add paste your .env variables, updating for production as needed:
BETTER_AUTH_SECRET: New secure valueBETTER_AUTH_URL: Your production domainNEXT_PUBLIC_APP_URL: Your production domainNEXT_PUBLIC_APP_NAME: Your application namePASSKEY_RP_ID: Your production domainCONVEX_DEPLOYMENT:prod:your-deployment-nameNEXT_PUBLIC_CONVEX_URL: Production Convex URLNEXT_PUBLIC_CONVEX_SITE_URL: Production Convex Site URL
Critical: BETTER_AUTH_SECRET must be different from development and properly generated with openssl rand -base64 32.
- Generate JWKS keys for production:
bunx convex run betterAuth/auth:rotateKeys --prod | bunx convex env set JWKS --prod
JWKS key rotation will log out all existing users. Run this during low-traffic periods.
Prerequisite: Ensure you've run npx convex dev at least once to push the betterAuth/auth:rotateKeys function to your deployment before running this command.
- Deploy:
- Click "Deploy"
- Wait for build to complete (2-3 minutes)
- Vercel will provide a URL
Configure Custom Domain (Optional)
-
In Vercel project settings:
- Go to "Domains"
- Add your domain
- Follow DNS instructions
-
Update environment variables:
BETTER_AUTH_URL=https://yourdomain.com NEXT_PUBLIC_APP_URL=https://yourdomain.com PASSKEY_RP_ID=yourdomain.com -
Update Convex environment:
npx convex env set BETTER_AUTH_URL "https://yourdomain.com" --prod
DNS changes can take up to 48 hours but usually propagate within minutes.
Verify Deployment
-
Visit your production URL
-
Test authentication:
- Register a new account
- Check email verification
- Test OTP login
- Try passkey (if on HTTPS)
-
Check Convex:
- Go to Convex dashboard
- Verify data is being created
- Check production deployment logs
-
Test key features:
- Create organization
- Invite members
- Test 2FA
- Verify admin panel (if applicable)
Post-Deployment
Set Up Email Domain
For production emails, configure your domain in Resend:
- Add domain in Resend dashboard
- Add DNS records provided by Resend
- Verify domain
- Update
EMAIL_FROMto use your domain
Until domain is verified, emails may go to spam or fail to send.
Configure Billing
If using Autumn for payments:
- Set up Autumn account
- Get production API key
- Add
AUTUMN_API_KEYto Vercel - Test payment flows
Set Up Monitoring (Optional)
Configure Sentry for error tracking:
- Create Sentry project
- Get DSN from Sentry dashboard
- Configure in these files:
instrumentation.ts(server-side)instrumentation-client.ts(client-side)sentry.edge.config.ts(edge runtime)sentry.server.config.ts(server-side config)
Sentry configuration is done in code files, not environment variables. You can use the Sentry Wizard (@sentry/wizard) to help set this up.
Environment Variables Checklist
Required for production:
-
BETTER_AUTH_SECRET(new, secure value) -
BETTER_AUTH_URL(your domain) -
NEXT_PUBLIC_APP_URL(your domain) -
NEXT_PUBLIC_APP_NAME(your app name) -
CONVEX_DEPLOYMENT(production) -
NEXT_PUBLIC_CONVEX_URL(production) -
NEXT_PUBLIC_CONVEX_SITE_URL(production) -
PASSKEY_RP_ID(your domain) -
RESEND_API_KEY(production key) -
EMAIL_FROM(verified domain) -
AUTUMN_API_KEY(optional, required only for organization billing) -
JWKS(generated withbunx convex run betterAuth/auth:rotateKeys --prod | bunx convex env set JWKS --prod)
Optional:
- Configure Sentry in code files (if using monitoring)
Continuous Deployment
Vercel automatically redeploys when you push to your main branch:
git add .
git commit -m "Update feature"
git push origin mainVercel will:
- Detect the push
- Start new build
- Run tests (if configured)
- Deploy automatically
- Notify you of status
Preview deployments are created for pull requests automatically.
Troubleshooting
Build Fails
Check:
- Build logs in Vercel dashboard
- All dependencies in
package.json - TypeScript errors locally
- Environment variables set correctly
Common issues:
- Missing environment variables
- TypeScript errors
- Dependency conflicts
Authentication Not Working
Verify:
BETTER_AUTH_SECRETis set and different from devBETTER_AUTH_URLmatches your actual URL- Convex environment variables match
- Cookies are not blocked (HTTPS required)
Emails Not Sending
Check:
RESEND_API_KEYis production key- Domain is verified in Resend
EMAIL_FROMuses verified domain- DNS records are configured
- Check Resend logs
Passkeys Not Working
Ensure:
- Using HTTPS (not HTTP)
PASSKEY_RP_IDmatches domain- Domain doesn't have port number
- Browser supports WebAuthn
Database Connection Issues
Verify:
- Convex deployment is active
- All three Convex URLs are correct
- Convex environment variables set
- Check Convex dashboard logs
Performance Optimization
Optimize Images
Next.js automatically optimizes images. Use the Image component:
import Image from 'next/image';
<Image
src="/logo.png"
alt="Logo"
width={200}
height={200}
/>Security Best Practices
- HTTPS Only: Never use HTTP in production
- Strong Secrets: Generate with
openssl rand -base64 32 - Different Secrets: Dev and prod must be different
- Environment Variables: Never commit to git
- CORS: Configure appropriately for your domain
- Rate Limiting: Consider adding rate limiting
- Security Headers: Vercel sets these by default
- Regular Updates: Keep dependencies updated
Scaling
Unstack Pro scales automatically on Vercel and Convex:
- Serverless Functions: Auto-scale with traffic
- Convex: Scales automatically
- No Infrastructure: Fully managed
Backup Strategy
Database Backups
Convex automatically backs up your data. To export:
- Go to Convex dashboard
- Settings → Export
- Download backup
Code Backups
Your code is already backed up in GitHub. Ensure:
- Regular commits
- Protected main branch
- Pull request reviews
- Tagged releases
Monitoring
Vercel Analytics
Enable in Vercel dashboard for:
- Page views
- Performance metrics
- User analytics
Convex Logs
Monitor in Convex dashboard:
- Function calls
- Error rates
- Performance
- Data changes
Sentry (Optional)
For error tracking:
- Catches runtime errors
- Tracks error trends
- User impact analysis
- Source maps for debugging
Support
If issues persist:
- Check Vercel Docs
- Check Convex Docs
- Check better-convex Docs - Our Better Auth + Convex integration
- Check Better Auth Docs
- Review GitHub issues
- Contact support
Next Steps
After deployment:
- Test all features thoroughly
- Set up monitoring
- Configure backup schedule
- Plan for scaling
- Document custom changes
- Train team on admin panel
- Set up staging environment (optional)
Consider setting up a staging environment that mirrors production for testing changes before they go live.