Overview
This guide walks you through deploying Dashtray to production on Cloudflare Pages with Convex backend.Deployment Stack:
- Frontend: Cloudflare Pages
- Backend: Convex (serverless)
- Database: Convex (built-in)
- Authentication: Better Auth
- Payments: Dodo Payments
Prerequisites
Before deploying, ensure you have:- A Cloudflare account
- A Convex account
- A custom domain (optional but recommended)
- All required API keys and credentials
- Git repository with your code
Deployment Steps
1. Deploy Convex Backend
Create Production Deployment
- Create a new production deployment
- Deploy all Convex functions
- Generate your production Convex URL
2. Configure OAuth Applications
Google OAuth
- Go to Google Cloud Console
- Create a new project or select existing
- Enable Google+ API
- Create OAuth 2.0 credentials
- Add authorized redirect URIs:
- Copy Client ID and Secret to Convex env
GitHub OAuth
- Go to GitHub Settings
- Click New OAuth App
- Set Authorization callback URL:
- Copy Client ID and Secret to Convex env
3. Configure Brevo Email
Verify Domain
- Go to Brevo Settings
- Add your domain
- Add DNS records (SPF, DKIM, DMARC)
- Wait for verification (can take up to 48 hours)
Create API Key
- Go to Brevo API Keys
- Create new API key with full access
- Copy to Convex env
4. Deploy to Cloudflare Pages
Connect Repository
- Go to Cloudflare Dashboard
- Navigate to Pages
- Click Create a project
- Connect your Git repository
Configure Build Settings
Set the following build configuration:
- Framework preset: SvelteKit
- Build command:
pnpm build - Build output directory:
.svelte-kit/cloudflare - Root directory:
/(or your monorepo path)
Set Environment Variables
Add environment variables in Cloudflare Pages:
Get your Convex URLs from the Convex dashboard after deployment.
5. Configure Custom Domain
Add Custom Domain
- In Cloudflare Pages, go to Custom domains
- Click Set up a custom domain
- Enter your domain (e.g.,
app.yourdomain.com)
Enable SSL
Cloudflare automatically provisions SSL certificate.Wait 5-10 minutes for certificate to be issued.
6. Configure Dodo Payments
Create Live Mode Account
- Go to Dodo Payments Dashboard
- Switch to Live Mode
- Complete business verification
Post-Deployment Checklist
Security
- All environment variables set correctly
- OAuth redirect URIs configured
- Webhook signatures verified
- SSL certificate active
- API keys rotated from development
- Rate limiting configured
Monitoring
- Sentry error tracking configured
- PostHog analytics configured
- Uptime monitoring set up (UptimeRobot)
- Cloudflare analytics enabled
- Convex logs monitored
- Domain verified in Brevo
- SPF/DKIM/DMARC records added
- Test emails sent successfully
- Email templates reviewed
- Unsubscribe links working
Payments
- Dodo Payments in live mode
- Webhook endpoint verified
- Test subscription flow
- Pricing tiers configured
- Trial periods set correctly
Testing
- Sign up flow works
- Email verification works
- OAuth login works
- Integration connections work
- Dashboard displays correctly
- Subscription upgrade works
- Webhooks receive data
Environment Variables Reference
Required Variables
| Variable | Location | Description |
|---|---|---|
SITE_URL | Convex | Your production domain |
BETTER_AUTH_SECRET | Convex | Auth secret (32+ chars) |
BREVO_API_KEY | Convex | Brevo API key |
RESET_EMAIL_FROM | Convex | Email sender address |
PUBLIC_CONVEX_URL | Cloudflare | Convex deployment URL |
PUBLIC_CONVEX_SITE_URL | Cloudflare | Convex site URL |
Optional Variables
| Variable | Location | Description |
|---|---|---|
GOOGLE_CLIENT_ID | Convex | Google OAuth client ID |
GOOGLE_CLIENT_SECRET | Convex | Google OAuth secret |
GITHUB_CLIENT_ID | Convex | GitHub OAuth client ID |
GITHUB_CLIENT_SECRET | Convex | GitHub OAuth secret |
DODO_PAYMENTS_API_KEY | Convex | Dodo Payments API key |
DODO_PAYMENTS_ENVIRONMENT | Convex | live or test |
GEMINI_API_KEY | Convex | Google Gemini API key |
Troubleshooting
Build Failures
Problem: Cloudflare build fails. Solutions:- Check build logs for specific errors
- Verify pnpm-lock.yaml is committed
- Ensure all dependencies are in package.json
- Check Node.js version compatibility
Environment Variable Issues
Problem: App can’t connect to Convex. Solutions:- Verify PUBLIC_CONVEX_URL is set in Cloudflare
- Check that URL matches Convex dashboard
- Ensure no trailing slashes in URLs
- Redeploy after changing env vars
Email Not Sending
Problem: Emails not being delivered. Solutions:- Verify domain is verified in Brevo
- Check SPF/DKIM records are correct
- Test with Brevo’s test email feature
- Check Brevo API key has correct permissions
OAuth Errors
Problem: OAuth login fails. Solutions:- Verify redirect URIs match exactly
- Check OAuth credentials are for production
- Ensure SITE_URL is correct in Convex
- Test with incognito/private browsing
Webhook Failures
Problem: Webhooks not being received. Solutions:- Verify webhook URL is publicly accessible
- Check webhook signature verification
- Review webhook logs in provider dashboard
- Test with webhook testing tools
Rollback Procedure
If deployment fails, rollback quickly:Cloudflare Pages
- Go to Deployments tab
- Find last working deployment
- Click Rollback to this deployment
Convex
Monitoring & Alerts
Set Up Monitoring
-
Sentry - Error tracking
-
UptimeRobot - Uptime monitoring
- Add HTTP(s) monitor for your domain
- Set check interval to 5 minutes
- Configure alert contacts
-
Cloudflare Analytics - Traffic monitoring
- Enabled automatically
- View in Cloudflare dashboard
Configure Alerts
Set up alerts for:- Error rate > 1% - Sentry alert
- Response time > 2s - Cloudflare alert
- Downtime > 1 minute - UptimeRobot alert
- Failed deployments - Cloudflare email notification
Performance Optimization
Cloudflare Settings
- Enable Auto Minify (HTML, CSS, JS)
- Enable Brotli compression
- Set Browser Cache TTL to 4 hours
- Enable Always Use HTTPS
Convex Optimization
- Add indexes for common queries
- Use pagination for large datasets
- Implement caching where appropriate
- Monitor function execution times
Security Hardening
Headers
Add security headers insvelte.config.js:
Rate Limiting
Implement rate limiting inhooks.server.ts:
- Auth endpoints: 10 requests/minute
- API endpoints: 100 requests/minute
- Webhook endpoints: 200 requests/minute
Credential Rotation
Rotate credentials regularly:- API keys: Every 90 days
- OAuth secrets: Every 180 days
- Webhook secrets: Every 90 days
- Auth secrets: Every 365 days
Backup & Recovery
Convex Backups
Convex automatically backs up your data:- Frequency: Continuous
- Retention: 30 days
- Recovery: Contact Convex support
Manual Exports
Export data regularly (Scale tier):Support
Need deployment help?- Email: support@dashtray.com
- Documentation: Deployment Runbook
- Status: status.dashtray.com
Next Steps
Monitoring Setup
Configure monitoring and alerts
Production Checklist
Complete pre-launch checklist
Quick Reference
Common commands and URLs
Deployment Runbook
Detailed deployment procedures