Unstack Pro Docs

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

  1. Commit all changes:

    git add .
    git commit -m "Ready for deployment"
  2. Push to GitHub:

    git push origin HEAD   # your default branch (master or main)
  3. Verify .gitignore includes:

    • .env.local
    • .env
    • node_modules/
    • .next/

Configure Convex for Production

  1. Go to your Convex dashboard: dashboard.convex.dev

  2. Create production deployment:

    • Click your project
    • Go to "Settings"
    • Note your production deployment name
  3. 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_URL and PASSKEY_RP_ID)
  4. Save changes

Use different secrets for production! Never reuse development secrets.

Deploy to Vercel

  1. Go to vercel.com

  2. Import your repository:

    • Click "New Project"
    • Import from GitHub
    • Select your repository
  3. Configure project:

    • Framework Preset: Next.js
    • Root Directory: ./
    • Build Command: bun run build (runs tsgo --noEmit && next build --turbopack)
    • Output Directory: .next
  4. 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 domain
    • NEXT_PUBLIC_APP_NAME: Your application name
    • NEXT_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.

  1. 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)" --prod

    To 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.

  1. Deploy:
    • Click "Deploy"
    • Wait for build to complete (2-3 minutes)
    • Vercel will provide a URL

Configure Custom Domain (Optional)

  1. In Vercel project settings:

    • Go to "Domains"
    • Add your domain
    • Follow DNS instructions
  2. Update environment variables (Vercel + Convex):

    NEXT_PUBLIC_APP_URL=https://yourdomain.com
    PASSKEY_RP_ID=yourdomain.com
  3. 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

  1. Visit your production URL

  2. Test authentication:

    • Register a new account
    • Check email verification
    • Test OTP login
    • Try passkey (if on HTTPS)
  3. Check Convex:

    • Go to Convex dashboard
    • Verify data is being created
    • Check production deployment logs
  4. 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:

  1. Add domain in Resend dashboard
  2. Add DNS records provided by Resend
  3. Verify domain
  4. Update EMAIL_FROM to use your domain

Until domain is verified, emails may go to spam or fail to send.

Configure Billing

If using Autumn for payments:

  1. Set up an Autumn account and run bunx atmn push against your live account
  2. Get your production secret key (starts with am_sk_)
  3. Add AUTUMN_SECRET_KEY to both Vercel and the Convex deployment
  4. 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 time
  • SENTRY_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 with bunx 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_URL and NEXT_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 HEAD

Vercel will:

  1. Detect the push
  2. Start new build
  3. Run tests (if configured)
  4. Deploy automatically
  5. 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_SECRET is set on the Convex deployment and different from dev
  • JWKS is set on the production deployment
  • NEXT_PUBLIC_APP_URL matches your actual domain
  • Cookies are not blocked (HTTPS required)

Emails Not Sending

Check:

  • RESEND_API_KEY is production key
  • Domain is verified in Resend
  • EMAIL_FROM uses verified domain
  • DNS records are configured
  • Check Resend logs

Passkeys Not Working

Ensure:

  • Using HTTPS (not HTTP)
  • PASSKEY_RP_ID matches 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

  1. HTTPS Only: Never use HTTP in production
  2. Strong Secrets: Generate with openssl rand -base64 32
  3. Different Secrets: Dev and prod must be different
  4. Environment Variables: Never commit to git
  5. CORS: Configure appropriately for your domain
  6. Rate Limiting: Consider adding rate limiting
  7. Security Headers: Vercel sets these by default
  8. 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:

  1. Go to Convex dashboard
  2. Settings → Export
  3. 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:

  1. Check Vercel Docs
  2. Check Convex Docs
  3. Check better-convex Docs - Our Better Auth + Convex integration
  4. Check Better Auth Docs
  5. Review GitHub issues
  6. 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.

On this page