Vercel Deployment Guide
Complete checklist for deploying Raypx to Vercel with database, Redis, Stripe, and email services configuration
Project: Raypx - TanStack Start + React 19 + PostgreSQL + Redis + Stripe Platform: Vercel Created: 2025-01-19
Pre-Deployment Preparation (Local Verification)
✅ 1. Local Build Test
# Clean cache
pnpm clean
# Install dependencies
pnpm install
# Type check
pnpm typecheck
# Code check
pnpm check
# Full build
pnpm build
# Verify build output
ls -la apps/web/dist/client
ls -la apps/web/dist/server✅ Validation Standards:
- TypeScript: No errors
- Biome: No warnings
- Build: Success (exit code 0)
- Dist: Client and server files exist
✅ 2. Environment Variables Preparation
Create .env.production file (do NOT commit to git), prepare the following variables:
# Copy template
cp .env.example .env.production
# Edit production environment variables
# Below is the list of required variables🗄️ Database Setup (Choose 1 of 3)
Option 1: Neon (Recommended - Serverless PostgreSQL)
Advantages: Large free tier, Serverless, Auto-scaling
Steps:
- Visit https://neon.tech
- Create new project → Select region (suggest us-east-1 near Vercel)
- Get connection string:
DATABASE_URL=postgresql://user:pass@ep-xxx.us-east-1.aws.neon.tech/raypx?sslmode=require - Run database migrations:
DATABASE_URL="postgresql://..." pnpm --filter @raypx/db run db:migrate - Verify database:
DATABASE_URL="postgresql://..." pnpm --filter @raypx/db run db:studio
Option 2: Vercel Postgres (Easiest)
Advantages: Native Vercel integration, One-click connection
Steps:
- Vercel Dashboard → Storage → Create Database → Postgres
- Select project association
- Auto-inject environment variable
POSTGRES_URL - Modify
packages/db/src/envs.ts:DATABASE_URL: z.string().url().default(process.env.POSTGRES_URL || '') - Run migrations locally (connecting to Vercel Postgres):
vercel env pull .env.local pnpm --filter @raypx/db run db:migrate
Option 3: Any Standard PostgreSQL
Advantages: Most flexible, works with any PostgreSQL provider
Steps:
- Use any PostgreSQL hosting service (Railway, Render, DigitalOcean, etc.)
- Get connection string:
DATABASE_URL=postgresql://user:pass@host:5432/raypx?sslmode=require - Run migrations (same as Neon)
✅ Verify Database Connection:
# Test connection
DATABASE_URL="postgresql://..." psql -c "SELECT version();"
# View tables
DATABASE_URL="postgresql://..." pnpm --filter @raypx/db run db:studio🔴 Redis Setup (Choose 1 of 2)
Option 1: Vercel KV (Recommended - One-Click Integration)
Steps:
- Vercel Dashboard → Storage → Create Database → KV
- Select project association
- Auto-inject environment variables
KV_REST_API_URLandKV_REST_API_TOKEN - Modify
packages/redis/src/envs.ts:REDIS_URL: z.string().url().optional(), KV_REST_API_URL: z.string().url().optional(), KV_REST_API_TOKEN: z.string().optional(),
Option 2: Upstash Redis
Steps:
- Visit https://upstash.com
- Create Redis Database
- Select region (suggest us-east-1)
- Get REST API URL and Token:
REDIS_URL=https://xxx.upstash.io UPSTASH_REDIS_REST_TOKEN=AXXXxxx
⚠️ Note: Redis is optional. If not configured, caching will fallback to in-memory cache
✅ Verify Redis Connection:
# Test with redis-cli
redis-cli -u "redis://default:password@host:port"
PING💳 Stripe Configuration
1. Get API Keys
Production Keys (Dashboard → Developers → API keys):
STRIPE_SECRET_KEY=sk_live_xxxxxxxxxxxxx
STRIPE_PUBLISHABLE_KEY=pk_live_xxxxxxxxxxxxx⚠️ Test Keys (Verify with test environment first):
STRIPE_SECRET_KEY=sk_test_xxxxxxxxxxxxx
STRIPE_PUBLISHABLE_KEY=pk_test_xxxxxxxxxxxxx2. Configure Webhook
Steps:
-
Stripe Dashboard → Developers → Webhooks
-
Add endpoint:
URL: https://yourdomain.com/api/billing/webhook -
Select events to listen:
- ✅
checkout.session.completed - ✅
customer.subscription.created - ✅
customer.subscription.updated - ✅
customer.subscription.deleted - ✅
invoice.paid - ✅
invoice.payment_failed - ✅
payment_method.attached - ✅
checkout.session.async_payment_succeeded - ✅
checkout.session.async_payment_failed
- ✅
-
Get Webhook signing secret:
STRIPE_WEBHOOK_SECRET=whsec_xxxxxxxxxxxxx
✅ Test Webhook (Local):
# Install Stripe CLI
stripe listen --forward-to localhost:3000/api/billing/webhook
# Trigger test event
stripe trigger checkout.session.completed📧 Email Service Configuration (Resend)
1. Get API Key
Steps:
- Visit https://resend.com
- API Keys → Create API Key
- Configure:
RESEND_API_KEY=re_xxxxxxxxxxxxx RESEND_FROM=noreply@yourdomain.com
2. Verify Domain (Required for Production)
Steps:
- Resend → Domains → Add Domain
- Add DNS records:
Type: TXT Name: _resend Value: (Value provided by Resend) - Wait for verification (about 5-10 minutes)
⚠️ Testing Phase: You can use Resend's test domain onboarding@resend.dev
✅ Test Email Sending:
# Start email preview service
pnpm email:dev
# Visit http://localhost:3003
# Test sending emails🔐 Authentication Configuration (Better Auth)
Required Variables
# Better Auth secret (generate: openssl rand -base64 32)
AUTH_SECRET=your-super-secret-key-min-32-characters
# Better Auth URL (production domain)
BETTER_AUTH_URL=https://yourdomain.com
# OAuth providers (optional)
AUTH_GITHUB_ID=your_github_client_id
AUTH_GITHUB_SECRET=your_github_client_secret
AUTH_GOOGLE_ID=your_google_client_id.apps.googleusercontent.com
AUTH_GOOGLE_SECRET=your_google_client_secretGitHub OAuth Configuration (Optional)
Steps:
- GitHub Settings → Developer settings → OAuth Apps → New OAuth App
- Configure:
Application name: Raypx Homepage URL: https://yourdomain.com Authorization callback URL: https://yourdomain.com/api/auth/callback/github - Get Client ID and Secret
Google OAuth Configuration (Optional)
Steps:
- Google Cloud Console → APIs & Services → Credentials
- Create OAuth 2.0 Client ID
- Configure:
Authorized redirect URIs: https://yourdomain.com/api/auth/callback/google
🚀 Vercel Deployment Steps
1. Connect GitHub Repository
Steps:
- Visit https://vercel.com
- Import Project → Select GitHub repository
- Configure Project:
Framework Preset: Other Root Directory: ./ Build Command: pnpm build Output Directory: apps/web/dist Install Command: pnpm install
2. Configure Environment Variables
Vercel Dashboard → Settings → Environment Variables
Required Variables (Production):
# === App Configuration ===
NODE_ENV=production
VITE_SITE_URL=https://yourdomain.com
VITE_WEB_URL=https://yourdomain.com
# === Database ===
DATABASE_URL=postgresql://user:pass@host:5432/raypx
# === Redis (optional) ===
REDIS_URL=redis://default:pass@host:6379
# Or use Vercel KV (auto-injected)
# === Better Auth ===
AUTH_SECRET=your-super-secret-key-min-32-characters
BETTER_AUTH_URL=https://yourdomain.com
# === Stripe ===
STRIPE_SECRET_KEY=sk_live_xxxxxxxxxxxxx
VITE_STRIPE_PUBLISHABLE_KEY=pk_live_xxxxxxxxxxxxx
STRIPE_WEBHOOK_SECRET=whsec_xxxxxxxxxxxxx
# === Email (Resend) ===
RESEND_API_KEY=re_xxxxxxxxxxxxx
RESEND_FROM=noreply@yourdomain.com
AUTH_RESEND_KEY=re_xxxxxxxxxxxxx
# === Analytics (optional) ===
VITE_SENTRY_DSN=https://xxx@sentry.io/xxx
VITE_PUBLIC_POSTHOG_KEY=phc_xxxxxxxxxxxxx
VITE_PUBLIC_POSTHOG_HOST=https://app.posthog.com⚠️ Environment Variable Notes:
VITE_prefix variables are exposed to the client- Sensitive keys (SECRET, API_KEY) should NOT use
VITE_prefix - Ensure all variables are set to
Productionenvironment
3. Trigger Deployment
# Method 1: GitHub push
git add .
git commit -m "chore: prepare for deployment"
git push origin main
# Method 2: Use Vercel CLI
pnpm add -g vercel
vercel --prod
# Method 3: Vercel Dashboard manual trigger
# Deployments → Redeploy4. Post-Deployment Verification
✅ Checklist:
- Visit
https://yourdomain.comto confirm homepage loads - Test user registration (email verification sent)
- Test login/logout
- Test user profile update
- Test Stripe payment flow
- Check Vercel logs for errors
- Verify database writes data correctly
View Logs:
# Vercel CLI real-time logs
vercel logs
# Or visit Vercel Dashboard → Deployments → Click deployment → Logs🌍 Domain Configuration
1. Add Custom Domain
Steps:
- Vercel Dashboard → Settings → Domains
- Add Domain → Enter
yourdomain.com - Configure DNS:
Option 1: Use Vercel DNS (Recommended)
Change domain registrar's Nameservers:
ns1.vercel-dns.com
ns2.vercel-dns.comOption 2: Use CNAME
Type: CNAME
Name: www
Value: cname.vercel-dns.comOption 3: Use A Record
Type: A
Name: @
Value: 76.76.21.212. SSL Certificate
Vercel Auto-Configuration:
- Automatically issues Let's Encrypt certificate
- Auto-renewal
- Force HTTPS redirect
✅ Verify SSL:
curl -I https://yourdomain.com
# Check response headers for "strict-transport-security"🔧 Build Optimization Configuration
1. vercel.json Configuration (Optional)
{
"buildCommand": "pnpm build",
"outputDirectory": "apps/web/dist",
"devCommand": "pnpm dev",
"installCommand": "pnpm install",
"framework": null,
"regions": ["iad1"],
"functions": {
"apps/web/dist/server/**": {
"maxDuration": 30
}
},
"headers": [
{
"source": "/(.*)",
"headers": [
{
"key": "X-Content-Type-Options",
"value": "nosniff"
},
{
"key": "X-Frame-Options",
"value": "DENY"
},
{
"key": "X-XSS-Protection",
"value": "1; mode=block"
}
]
}
]
}2. Performance Optimization
package.json scripts:
{
"scripts": {
"vercel-build": "pnpm build"
}
}Cache Optimization:
- Vercel automatically caches
node_modules - Use
pnpmfor faster dependency installation - Turborepo caches build artifacts
🐛 Common Issues Troubleshooting
Issue 1: Build Failure - "Cannot find module"
Cause: pnpm workspace dependencies not resolved correctly
Solution:
# Ensure .npmrc exists
shamefully-hoist=true
# Clean and reinstall
rm -rf node_modules pnpm-lock.yaml
pnpm installIssue 2: Environment Variables Not Working
Cause: Environment variable scope error
Solution:
- Check Vercel environment variables set to
Production - Redeploy to trigger environment variable update
- Confirm
VITE_prefix variables injected at build time
Issue 3: Database Connection Failed
Cause: SSL connection issue or IP whitelist
Solution:
# Add SSL parameter to database URL
DATABASE_URL=postgresql://...?sslmode=require
# Neon/Supabase: Add Vercel IP to whitelist
# Or use "Allow all IPs" (not recommended for production)Issue 4: Stripe Webhook Not Working
Cause: Webhook signature verification failed
Solution:
- Confirm
STRIPE_WEBHOOK_SECRETis correct - Check Stripe Dashboard webhook endpoint URL
- View Vercel Function logs:
vercel logs --follow
Issue 5: Email Sending Failed
Cause: Resend domain not verified or API key error
Solution:
- Check Resend domain DNS configuration
- Use
onboarding@resend.devfor testing - Verify
RESEND_API_KEYis correct
📊 Post-Deployment Monitoring
1. Log Monitoring
# Real-time logs
vercel logs --follow
# Filter error logs
vercel logs --follow | grep ERROR2. Performance Monitoring
Vercel Analytics (Free):
- Vercel Dashboard → Analytics
- View:
- Requests per second
- Response time
- Error rate
- Geographic distribution
Sentry Error Monitoring (Recommended):
VITE_SENTRY_DSN=https://xxx@sentry.io/xxx3. Database Monitoring
Neon Dashboard:
- Query performance
- Connection count
- Storage usage
Drizzle Studio (Local):
DATABASE_URL="postgresql://..." pnpm --filter @raypx/db run db:studio✅ Final Checklist
Pre-Deployment (Local)
-
pnpm typecheckpasses -
pnpm checkpasses -
pnpm buildsucceeds - All TODO code completed or commented
- .env.example updated
Vercel Configuration
- GitHub repository connected
- Build command configured correctly
- Production environment variables set
- Database created and migrated
- Redis configured (optional)
External Services
- Stripe API keys configured
- Stripe Webhook created
- Resend API key configured
- Resend domain verified (production)
- GitHub/Google OAuth configured (optional)
Post-Deployment Verification
- Homepage loads normally
- User registration/login works
- Email sending works
- Payment flow works
- Webhook receiving works
- No critical errors in logs
Domain and SSL
- Custom domain added
- DNS configured
- SSL certificate active
- HTTPS forced redirect
🚀 Quick Deployment Commands
# 1. Local verification
pnpm clean && pnpm install && pnpm build
# 2. Commit code
git add .
git commit -m "chore: prepare for deployment"
git push origin main
# 3. Deploy with Vercel CLI (optional)
vercel --prod
# 4. Verify deployment
curl -I https://yourdomain.com
vercel logs --follow📚 Reference Resources
- Vercel Docs: https://vercel.com/docs
- TanStack Start Deployment: https://tanstack.com/start/latest/docs/deployment
- Neon Docs: https://neon.tech/docs
- Stripe Webhooks: https://stripe.com/docs/webhooks
- Resend Docs: https://resend.com/docs
- Better Auth: https://better-auth.com
Created: 2025-01-19 Last Updated: 2025-01-19 Maintained By: Raypx Team
Last updated on
