This guide covers deployment strategies for the CastQuest Frames platform, including both User and Admin dashboards.
- Prerequisites
- Environment Configuration
- Dashboard Deployments
- Vercel Deployment
- Docker Deployment
- AWS Deployment
- Database Setup
- Monitoring & Maintenance
- Troubleshooting
- Node.js 20+ (LTS recommended)
- pnpm 9+
- Git
- PostgreSQL 15+
- Redis 7+ (for admin dashboard)
- GitHub repository access
- Cloud platform credentials (Vercel/AWS/other)
- Database connection strings
- Domain names (for production)
Create apps/web/.env.production:
# Application
NODE_ENV=production
NEXT_PUBLIC_APP_URL=https://castquest.io
# API Configuration
NEXT_PUBLIC_API_URL=https://api.castquest.io
NEXT_PUBLIC_FARCASTER_API_KEY=your_farcaster_api_key
# Database
DATABASE_URL=postgresql://user:pass@host:5432/castquest?sslmode=require
# Authentication
NEXTAUTH_URL=https://castquest.io
NEXTAUTH_SECRET=your_nextauth_secret_min_32_chars
# Feature Flags
NEXT_PUBLIC_ENABLE_ANALYTICS=true
NEXT_PUBLIC_MARKETPLACE_ENABLED=true
NEXT_PUBLIC_AI_BUILDER_ENABLED=true
# Storage (Optional)
AWS_S3_BUCKET=castquest-media
AWS_ACCESS_KEY_ID=your_access_key
AWS_SECRET_ACCESS_KEY=your_secret_key
AWS_REGION=us-east-1
# Analytics (Optional)
NEXT_PUBLIC_GA_ID=G-XXXXXXXXXX
NEXT_PUBLIC_POSTHOG_KEY=your_posthog_key
# Smart Brain (Optional)
SMART_BRAIN_API_KEY=your_brain_api_key
SMART_BRAIN_ENDPOINT=https://brain.castquest.ioCreate apps/admin/.env.production:
# Application
NODE_ENV=production
NEXT_PUBLIC_APP_URL=https://admin.castquest.io
# API Configuration
NEXT_PUBLIC_API_URL=https://admin.castquest.io
NEXT_PUBLIC_ADMIN_SECRET=your_admin_secret_min_32_chars
# Database
DATABASE_URL=postgresql://user:pass@host:5432/castquest?sslmode=require
# Redis (Required for admin)
REDIS_URL=redis://user:pass@host:6379?ssl=true
# Authentication
ADMIN_JWT_SECRET=your_jwt_secret_min_32_chars
ADMIN_SESSION_DURATION=86400
# Security
ENABLE_2FA=true
MAX_LOGIN_ATTEMPTS=5
RATE_LIMIT_REQUESTS=100
RATE_LIMIT_WINDOW=60
# Risk Management
ENABLE_RISK_DETECTION=true
RISK_DETECTION_THRESHOLD=0.85
AI_RISK_MODEL_VERSION=v2.0
# Monitoring
MONITORING_INTERVAL=30000
ENABLE_AUDIT_LOG=true
ALERT_WEBHOOK_URL=https://alerts.castquest.io/webhook
# System Health
ENABLE_HEALTH_CHECKS=true
HEALTH_CHECK_INTERVAL=60000Test production builds locally before deploying:
# Build both dashboards
pnpm build
# Test user dashboard
cd apps/web
pnpm start
# Test admin dashboard (in new terminal)
cd apps/admin
PORT=3001 pnpm start- All environment variables configured
- Database migrations applied
- Assets optimized and compressed
- Security headers configured
- Rate limiting enabled
- Monitoring setup complete
- Backup strategy in place
- SSL certificates valid
- Domain DNS configured
- CDN configured (optional)
Vercel is the recommended platform for Next.js deployments.
- Install Vercel CLI
npm i -g vercel- Deploy User Dashboard
cd apps/web
vercel
# Follow prompts:
# - Set up and deploy: Y
# - Which scope: Your account/org
# - Link to existing project: N
# - Project name: castquest-user-dashboard
# - Directory: ./
# - Override settings: N- Configure Environment Variables
# Set production environment variables
vercel env add NEXT_PUBLIC_API_URL production
vercel env add DATABASE_URL production
vercel env add NEXTAUTH_SECRET production
# ... add all required variables- Deploy to Production
vercel --prod- Configure Domain
vercel domains add castquest.io
# Follow DNS configuration instructions- Deploy Admin Dashboard
cd apps/admin
vercel
# Project name: castquest-admin-dashboard- Configure Environment Variables
vercel env add NEXT_PUBLIC_ADMIN_SECRET production
vercel env add DATABASE_URL production
vercel env add REDIS_URL production
vercel env add ADMIN_JWT_SECRET production
# ... add all required variables- Deploy to Production
vercel --prod- Configure Admin Domain
vercel domains add admin.castquest.ioUser Dashboard (apps/web/vercel.json):
{
"buildCommand": "pnpm build",
"devCommand": "pnpm dev",
"installCommand": "pnpm install",
"framework": "nextjs",
"regions": ["iad1", "sfo1"],
"headers": [
{
"source": "/(.*)",
"headers": [
{
"key": "X-Content-Type-Options",
"value": "nosniff"
},
{
"key": "X-Frame-Options",
"value": "DENY"
},
{
"key": "X-XSS-Protection",
"value": "1; mode=block"
}
]
}
]
}Admin Dashboard (apps/admin/vercel.json):
{
"buildCommand": "pnpm build",
"devCommand": "pnpm dev",
"installCommand": "pnpm install",
"framework": "nextjs",
"regions": ["iad1"],
"headers": [
{
"source": "/(.*)",
"headers": [
{
"key": "X-Content-Type-Options",
"value": "nosniff"
},
{
"key": "X-Frame-Options",
"value": "DENY"
},
{
"key": "Strict-Transport-Security",
"value": "max-age=63072000; includeSubDomains; preload"
}
]
}
],
"rewrites": [
{
"source": "/",
"destination": "/dashboard"
}
]
}For self-hosted or custom infrastructure deployments.
- User Dashboard Dockerfile (
apps/web/Dockerfile):
# Build stage
FROM node:20-alpine AS builder
# Install pnpm
RUN npm install -g pnpm@9
WORKDIR /app
# Copy workspace files
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./
COPY apps/web ./apps/web
COPY packages ./packages
# Install dependencies
RUN pnpm install --frozen-lockfile
# Build application
WORKDIR /app/apps/web
RUN pnpm build
# Production stage
FROM node:20-alpine AS runner
WORKDIR /app
ENV NODE_ENV production
ENV PORT 3000
# Create non-root user
RUN addgroup -g 1001 -S nodejs && \
adduser -S nextjs -u 1001
# Copy built application
COPY --from=builder --chown=nextjs:nodejs /app/apps/web/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/apps/web/.next/static ./.next/static
COPY --from=builder --chown=nextjs:nodejs /app/apps/web/public ./public
USER nextjs
EXPOSE 3000
CMD ["node", "server.js"]- Admin Dashboard Dockerfile (
apps/admin/Dockerfile):
# Build stage
FROM node:20-alpine AS builder
RUN npm install -g pnpm@9
WORKDIR /app
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./
COPY apps/admin ./apps/admin
COPY packages ./packages
RUN pnpm install --frozen-lockfile
WORKDIR /app/apps/admin
RUN pnpm build
# Production stage
FROM node:20-alpine AS runner
WORKDIR /app
ENV NODE_ENV production
ENV PORT 3001
RUN addgroup -g 1001 -S nodejs && \
adduser -S nextjs -u 1001
COPY --from=builder --chown=nextjs:nodejs /app/apps/admin/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/apps/admin/.next/static ./.next/static
COPY --from=builder --chown=nextjs:nodejs /app/apps/admin/public ./public
USER nextjs
EXPOSE 3001
CMD ["node", "server.js"]- Docker Compose (
docker-compose.yml):
version: '3.8'
services:
# User Dashboard
user-dashboard:
build:
context: .
dockerfile: apps/web/Dockerfile
ports:
- "3000:3000"
environment:
- NODE_ENV=production
- DATABASE_URL=${DATABASE_URL}
- NEXTAUTH_URL=${NEXTAUTH_URL}
- NEXTAUTH_SECRET=${NEXTAUTH_SECRET}
depends_on:
- postgres
restart: unless-stopped
networks:
- castquest-network
# Admin Dashboard
admin-dashboard:
build:
context: .
dockerfile: apps/admin/Dockerfile
ports:
- "3001:3001"
environment:
- NODE_ENV=production
- DATABASE_URL=${DATABASE_URL}
- REDIS_URL=${REDIS_URL}
- ADMIN_JWT_SECRET=${ADMIN_JWT_SECRET}
depends_on:
- postgres
- redis
restart: unless-stopped
networks:
- castquest-network
# PostgreSQL Database
postgres:
image: postgres:15-alpine
environment:
- POSTGRES_USER=${DB_USER:-castquest}
- POSTGRES_PASSWORD=${DB_PASSWORD}
- POSTGRES_DB=${DB_NAME:-castquest}
volumes:
- postgres_data:/var/lib/postgresql/data
ports:
- "5432:5432"
restart: unless-stopped
networks:
- castquest-network
# Redis Cache
redis:
image: redis:7-alpine
command: redis-server --requirepass ${REDIS_PASSWORD}
ports:
- "6379:6379"
volumes:
- redis_data:/data
restart: unless-stopped
networks:
- castquest-network
# Nginx Reverse Proxy
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- ./ssl:/etc/nginx/ssl:ro
depends_on:
- user-dashboard
- admin-dashboard
restart: unless-stopped
networks:
- castquest-network
networks:
castquest-network:
driver: bridge
volumes:
postgres_data:
redis_data:- Deploy with Docker Compose:
# Create .env file
cp .env.example .env
# Edit .env with production values
# Build images
docker-compose build
# Start services
docker-compose up -d
# View logs
docker-compose logs -f
# Check status
docker-compose ps
# Stop services
docker-compose down- Setup AWS CLI
# Install AWS CLI
brew install awscli # macOS
# or
pip install awscli # Python
# Configure credentials
aws configure- Create ECR Repositories
# User dashboard repository
aws ecr create-repository \
--repository-name castquest/user-dashboard \
--region us-east-1
# Admin dashboard repository
aws ecr create-repository \
--repository-name castquest/admin-dashboard \
--region us-east-1- Build and Push Images
# Login to ECR
aws ecr get-login-password --region us-east-1 | \
docker login --username AWS --password-stdin \
${AWS_ACCOUNT_ID}.dkr.ecr.us-east-1.amazonaws.com
# Build user dashboard
docker build -t castquest/user-dashboard -f apps/web/Dockerfile .
docker tag castquest/user-dashboard:latest \
${AWS_ACCOUNT_ID}.dkr.ecr.us-east-1.amazonaws.com/castquest/user-dashboard:latest
docker push ${AWS_ACCOUNT_ID}.dkr.ecr.us-east-1.amazonaws.com/castquest/user-dashboard:latest
# Build admin dashboard
docker build -t castquest/admin-dashboard -f apps/admin/Dockerfile .
docker tag castquest/admin-dashboard:latest \
${AWS_ACCOUNT_ID}.dkr.ecr.us-east-1.amazonaws.com/castquest/admin-dashboard:latest
docker push ${AWS_ACCOUNT_ID}.dkr.ecr.us-east-1.amazonaws.com/castquest/admin-dashboard:latest- Create ECS Task Definitions (
ecs-task-user.json):
{
"family": "castquest-user-dashboard",
"networkMode": "awsvpc",
"requiresCompatibilities": ["FARGATE"],
"cpu": "512",
"memory": "1024",
"containerDefinitions": [
{
"name": "user-dashboard",
"image": "${AWS_ACCOUNT_ID}.dkr.ecr.us-east-1.amazonaws.com/castquest/user-dashboard:latest",
"portMappings": [
{
"containerPort": 3000,
"protocol": "tcp"
}
],
"environment": [
{
"name": "NODE_ENV",
"value": "production"
}
],
"secrets": [
{
"name": "DATABASE_URL",
"valueFrom": "arn:aws:secretsmanager:us-east-1:${AWS_ACCOUNT_ID}:secret:castquest/database-url"
}
],
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "/ecs/castquest-user-dashboard",
"awslogs-region": "us-east-1",
"awslogs-stream-prefix": "ecs"
}
}
}
]
}- Deploy to ECS
# Register task definition
aws ecs register-task-definition \
--cli-input-json file://ecs-task-user.json
# Create/Update service
aws ecs update-service \
--cluster castquest \
--service user-dashboard \
--task-definition castquest-user-dashboard \
--force-new-deployment- Run Migrations
# Development
pnpm prisma migrate dev
# Production
pnpm prisma migrate deploy- Seed Database (optional)
pnpm prisma db seed- Backup Database
# Create backup
pg_dump $DATABASE_URL > backup-$(date +%Y%m%d).sql
# Restore backup
psql $DATABASE_URL < backup-20260105.sql- Configure Redis
# For production, enable password and persistence
redis-server --requirepass your_redis_password --save 900 1- Test Connection
redis-cli -h host -p 6379 -a password pingUser Dashboard Health Endpoint: /api/health
{
"status": "healthy",
"timestamp": "2026-01-05T12:00:00Z",
"version": "1.0.0",
"uptime": 86400
}Admin Dashboard Health Endpoint: /api/health
{
"status": "healthy",
"timestamp": "2026-01-05T12:00:00Z",
"database": "connected",
"redis": "connected",
"services": {
"risk_detection": "operational",
"monitoring": "operational"
}
}- Logging
# View application logs
docker-compose logs -f user-dashboard
docker-compose logs -f admin-dashboard
# AWS CloudWatch
aws logs tail /ecs/castquest-user-dashboard --follow- Metrics
- Setup CloudWatch dashboards for CPU, memory, network
- Configure alerts for high error rates
- Monitor database connections and query performance
- Track API response times
- Uptime Monitoring
- Use services like UptimeRobot, Pingdom, or custom solutions
- Monitor both dashboard endpoints
- Check SSL certificate expiration
- Verify DNS resolution
- Database Backups
# Daily automated backups
0 2 * * * pg_dump $DATABASE_URL | gzip > /backups/db-$(date +\%Y\%m\%d).sql.gz- Application State
- Backup environment variables (encrypted)
- Backup configuration files
- Document deployment procedures
Build Failures
# Clear build cache
rm -rf .next node_modules/.cache
pnpm install --force
pnpm buildEnvironment Variables Not Loading
# Verify .env files exist
ls -la apps/web/.env.production
ls -la apps/admin/.env.production
# Check variable names (must start with NEXT_PUBLIC_ for client-side)Database Connection Issues
# Test connection
psql $DATABASE_URL -c "SELECT 1"
# Check connection string format
# Should be: postgresql://user:pass@host:port/db?sslmode=requireMemory Issues
# Increase Node.js memory
NODE_OPTIONS="--max-old-space-size=4096" pnpm build
# Or in Dockerfile
ENV NODE_OPTIONS="--max-old-space-size=2048"Port Already in Use
# Find and kill process
lsof -ti:3000 | xargs kill -9
lsof -ti:3001 | xargs kill -9Vercel Rollback
# List deployments
vercel ls
# Rollback to specific deployment
vercel rollback [deployment-url]Docker Rollback
# Use previous image tag
docker-compose down
# Edit docker-compose.yml to use previous tag
docker-compose up -dDatabase Rollback
# Restore from backup
psql $DATABASE_URL < backup-previous.sql
# Or use Prisma
pnpm prisma migrate resolve --rolled-back migration_nameBefore deploying to production:
- All secrets stored securely (not in code)
- HTTPS enabled with valid SSL certificates
- Security headers configured
- Rate limiting enabled
- CORS properly configured
- Database connections use SSL
- Admin dashboard has additional authentication
- 2FA enabled for admin accounts
- Audit logging enabled
- Regular security updates scheduled
- Backup and disaster recovery tested
- Monitoring and alerting configured
- Vercel Documentation
- Docker Documentation
- AWS ECS Documentation
- Next.js Deployment
- PostgreSQL Documentation
For deployment issues:
- 📖 Check docs/DASHBOARDS.md
- 🐛 Report Issues
- 💬 Discord Support
- 📧 Email Support
Last Updated: 2026-01-05
Version: 1.0.0