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 HEAD # your default branch (master or 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 the Convex deployment environment variables (the Section 2 vars from Environment Variables) —
BETTER_AUTH_SECRET,JWKS,EMAIL_FROM,RESEND_API_KEY,AUTUMN_SECRET_KEY,PASSKEY_RP_ID,NEXT_PUBLIC_APP_URL,NEXT_PUBLIC_APP_NAME:- Use
bunx convex env set NAME "value" --prod, or - Go to "Settings" > "Environment Variables" tab in the dashboard and add them,
using production values (production domain for
NEXT_PUBLIC_APP_URLandPASSKEY_RP_ID)
- Use
-
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:
bun run build(runstsgo --noEmit && next build --turbopack) - Output Directory:
.next
-
Add environment variables (the Next.js side — see the Section 1 vars in Environment Variables):
Go to "Environment Variables" and add your production values:
NEXT_PUBLIC_APP_URL: Your production domainNEXT_PUBLIC_APP_NAME: Your application nameNEXT_PUBLIC_CONVEX_URL: Production Convex URL (….convex.cloud)NEXT_PUBLIC_CONVEX_SITE_URL: Production Convex site URL (….convex.site)NEXT_PUBLIC_SUPPORT_EMAIL: Support address (optional)AUTUMN_SECRET_KEY: Autumn secret key — also required on the Convex deployment (the Next.js billing routes read it here at runtime)NEXT_PUBLIC_SENTRY_DSN,SENTRY_ORG,SENTRY_PROJECT,SENTRY_AUTH_TOKEN: Sentry (optional — leave unset to disable)
BETTER_AUTH_SECRET, JWKS, EMAIL_FROM, RESEND_API_KEY, PASSKEY_RP_ID and
AUTUMN_SECRET_KEY also live on the Convex deployment (set in the previous
step), not just on Vercel. AUTUMN_SECRET_KEY is needed in both.
-
Generate JWKS keys for the production deployment (once functions are pushed):
# Initial key set bunx convex env set JWKS "$(bunx convex run betterAuth/auth:getLatestJwks --prod)" --prodTo rotate later:
bunx convex env set JWKS "$(bunx convex run betterAuth/auth:rotateKeys --prod)" --prod
JWKS key rotation will log out all existing users. Run rotation during low-traffic periods.
Prerequisite: run bunx convex deploy (or bun convex dev at least once) to push the betterAuth/auth functions to your production deployment before running these commands.
- 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 (Vercel + Convex):
NEXT_PUBLIC_APP_URL=https://yourdomain.com PASSKEY_RP_ID=yourdomain.com -
Update the Convex deployment:
bunx convex env set NEXT_PUBLIC_APP_URL "https://yourdomain.com" --prod bunx convex env set PASSKEY_RP_ID "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 an Autumn account and run
bunx atmn pushagainst your live account - Get your production secret key (starts with
am_sk_) - Add
AUTUMN_SECRET_KEYto both Vercel and the Convex deployment - Test the checkout and portal flows
AUTUMN_SECRET_KEY must be set on both Vercel (the Next.js billing routes read
it at runtime) and the Convex deployment (the auth hooks read it). Missing it in
either place breaks billing.
Set Up Monitoring (Optional)
Sentry is environment-variable driven — no code changes are needed. Set these in Vercel to enable it:
NEXT_PUBLIC_SENTRY_DSN— your Sentry project DSN (when empty, Sentry is disabled)SENTRY_ORG,SENTRY_PROJECT— used at build timeSENTRY_AUTH_TOKEN— enables source-map upload during the build
Leave NEXT_PUBLIC_SENTRY_DSN unset to disable Sentry entirely — the SDK no-ops,
and builds skip source-map upload when SENTRY_AUTH_TOKEN is missing.
Environment Variables Checklist
Vercel (Next.js runtime):
-
NEXT_PUBLIC_APP_URL(your domain) -
NEXT_PUBLIC_APP_NAME(your app name) -
NEXT_PUBLIC_CONVEX_URL(production.convex.cloud) -
NEXT_PUBLIC_CONVEX_SITE_URL(production.convex.site) -
AUTUMN_SECRET_KEY(also on Convex) -
NEXT_PUBLIC_SUPPORT_EMAIL(optional) -
NEXT_PUBLIC_SENTRY_DSN+SENTRY_ORG/SENTRY_PROJECT/SENTRY_AUTH_TOKEN(optional)
Convex deployment:
-
BETTER_AUTH_SECRET(new, secure value) -
JWKS(generated withbunx convex env set JWKS "$(bunx convex run betterAuth/auth:getLatestJwks --prod)" --prod) -
RESEND_API_KEY(production key) -
EMAIL_FROM(verified domain) -
AUTUMN_SECRET_KEY(also on Vercel) -
PASSKEY_RP_ID(your domain) -
NEXT_PUBLIC_APP_URLandNEXT_PUBLIC_APP_NAME
Continuous Deployment
Vercel automatically redeploys when you push to your default branch:
git add .
git commit -m "Update feature"
git push origin HEADVercel 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 on the Convex deployment and different from devJWKSis set on the production deploymentNEXT_PUBLIC_APP_URLmatches your actual domain- 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.