Forge Web - Deployment Guide
This guide covers deploying the Forge web application to various hosting platforms.
Prerequisites
Required Accounts
| Service | Purpose | Required |
|---|---|---|
| Turso | Database hosting | Yes |
| Azure AD | Authentication | Yes |
| LiveKit Cloud | Voice/video calling | Optional |
| Vercel/Railway/etc. | App hosting | Yes |
Required Tools
| Tool | Version | Purpose |
|---|---|---|
| Node.js | 18+ | Runtime |
| pnpm | 8+ | Package manager |
Environment Configuration
Required Environment Variables
Create a .env file with the following variables:
# Authentication (Required)
AUTH_SECRET="generate-a-random-string-here"
AUTH_MICROSOFT_ENTRA_ID_ID="your-azure-client-id"
AUTH_MICROSOFT_ENTRA_ID_SECRET="your-azure-client-secret"
AUTH_MICROSOFT_ENTRA_ID_ISSUER="https://login.microsoftonline.com/your-tenant-id/v2.0"
# Database (Required)
TURSO_DATABASE_URL="libsql://your-database.turso.io"
TURSO_AUTH_TOKEN="your-turso-auth-token"
# Application URL (Required)
NEXT_PUBLIC_APP_URL="https://your-domain.com"
# LiveKit (Optional - for calling features)
LIVEKIT_URL="wss://your-app.livekit.cloud"
LIVEKIT_API_KEY="your-livekit-api-key"
LIVEKIT_API_SECRET="your-livekit-api-secret"Generate AUTH_SECRET
openssl rand -base64 32External Services Setup
1. Turso Database
Create a Database
# Install Turso CLI
curl -sSfL https://get.tur.so/install.sh | bash
# Login to Turso
turso auth login
# Create a database
turso db create forge-production
# Get the database URL
turso db show forge-production --url
# Output: libsql://forge-production-yourname.turso.io
# Create an auth token
turso db tokens create forge-production
# Output: your-auth-tokenInitialize Schema
The schema is automatically applied when you run:
npx prisma db push2. Azure AD (Microsoft Entra ID)
Register Application
- Go to Azure Portal
- Navigate to Azure Active Directory → App registrations
- Click New registration
- Configure:
- Name: Forge Web
- Supported account types: Accounts in this organizational directory only
- Redirect URI: Web -
https://your-domain.com/api/auth/callback/microsoft-entra-id
Configure Authentication
- Go to Authentication
- Add redirect URI for your production domain
- Enable ID tokens under Implicit grant
Create Client Secret
- Go to Certificates & secrets
- Click New client secret
- Set expiration and create
- Copy the secret value immediately (shown only once)
Note Your Credentials
- Application (client) ID →
AUTH_MICROSOFT_ENTRA_ID_ID - Directory (tenant) ID → Use in issuer URL
- Client secret value →
AUTH_MICROSOFT_ENTRA_ID_SECRET
3. LiveKit Cloud (Optional)
- Sign up at LiveKit Cloud
- Create a new project
- Go to Settings → Keys
- Note your:
- URL →
LIVEKIT_URL - API Key →
LIVEKIT_API_KEY - API Secret →
LIVEKIT_API_SECRET
- URL →
Deployment Options
Option 1: Vercel (Recommended)
Vercel provides the easiest deployment for Next.js applications.
Deploy via CLI
# Install Vercel CLI
npm i -g vercel
# Deploy
vercel
# Set environment variables
vercel env add AUTH_SECRET
vercel env add AUTH_MICROSOFT_ENTRA_ID_ID
vercel env add AUTH_MICROSOFT_ENTRA_ID_SECRET
vercel env add AUTH_MICROSOFT_ENTRA_ID_ISSUER
vercel env add TURSO_DATABASE_URL
vercel env add TURSO_AUTH_TOKEN
vercel env add NEXT_PUBLIC_APP_URL
# Deploy to production
vercel --prodDeploy via GitHub
- Push your code to GitHub
- Go to vercel.com
- Click Import Project
- Select your GitHub repository
- Configure environment variables
- Click Deploy
Custom Domain
- Go to your project in Vercel
- Navigate to Settings → Domains
- Add your custom domain
- Update DNS records as instructed
- Update
NEXT_PUBLIC_APP_URLto your domain - Update Azure AD redirect URI
Option 2: Railway
# Install Railway CLI
npm i -g @railway/cli
# Login
railway login
# Initialize project
railway init
# Link to your repo
railway link
# Set environment variables
railway variables set AUTH_SECRET="your-secret"
railway variables set TURSO_DATABASE_URL="libsql://..."
# ... set all other variables
# Deploy
railway upOption 3: Docker
Dockerfile
FROM node:18-alpine AS base
# Install dependencies
FROM base AS deps
WORKDIR /app
COPY package.json pnpm-lock.yaml ./
RUN corepack enable pnpm && pnpm install --frozen-lockfile
# Build
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN corepack enable pnpm && pnpm prisma generate && pnpm build
# Production
FROM base AS runner
WORKDIR /app
ENV NODE_ENV=production
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
COPY --from=builder /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
USER nextjs
EXPOSE 3000
ENV PORT=3000
CMD ["node", "server.js"]Docker Compose
version: '3.8'
services:
forge:
build: .
ports:
- "3000:3000"
environment:
- AUTH_SECRET=${AUTH_SECRET}
- AUTH_MICROSOFT_ENTRA_ID_ID=${AUTH_MICROSOFT_ENTRA_ID_ID}
- AUTH_MICROSOFT_ENTRA_ID_SECRET=${AUTH_MICROSOFT_ENTRA_ID_SECRET}
- AUTH_MICROSOFT_ENTRA_ID_ISSUER=${AUTH_MICROSOFT_ENTRA_ID_ISSUER}
- TURSO_DATABASE_URL=${TURSO_DATABASE_URL}
- TURSO_AUTH_TOKEN=${TURSO_AUTH_TOKEN}
- NEXT_PUBLIC_APP_URL=${NEXT_PUBLIC_APP_URL}Build and Run
# Build image
docker build -t forge-web .
# Run container
docker run -p 3000:3000 --env-file .env forge-webOption 4: Self-Hosted (Node.js)
Build
# Install dependencies
pnpm install
# Generate Prisma client
pnpm prisma generate
# Build application
pnpm buildRun with PM2
# Install PM2
npm i -g pm2
# Start application
pm2 start npm --name "forge" -- start
# Save PM2 configuration
pm2 save
# Setup startup script
pm2 startupNginx Reverse Proxy
server {
listen 80;
server_name your-domain.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name your-domain.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache_bypass $http_upgrade;
}
}Database Migrations
Development
# Push schema changes to development database
pnpm prisma db pushProduction
# Generate migration files
pnpm prisma migrate dev --name your_migration_name
# Apply migrations in production
pnpm prisma migrate deploySeeding (Optional)
# Run seed script
pnpm prisma db seedPost-Deployment Checklist
Verify Deployment
- Application loads at your domain
- Sign in with Microsoft works
- User is redirected to dashboard after auth
- Can create/edit Ideas, Goals, Tasks
- Activity feed shows changes
- Search works (Cmd+K)
- Theme switching works
Security Checklist
- HTTPS is enabled
- AUTH_SECRET is unique and secure
- Azure AD redirect URIs are correct
- Database tokens haven’t expired
- No sensitive data in client-side code
Performance Checklist
- Enable caching headers
- Configure CDN for static assets
- Monitor database query performance
- Set up error tracking (Sentry, etc.)
Monitoring & Logging
Vercel Analytics
# Enable analytics in next.config.ts
module.exports = {
// ... other config
}
# Add analytics component
import { Analytics } from '@vercel/analytics/react';Custom Logging
The app uses Pino for structured logging:
import { logger } from "@/lib/logger";
logger.info({ userId, action: "created_idea" }, "User created an idea");Error Tracking
Integrate with Sentry:
pnpm add @sentry/nextjs
npx @sentry/wizard@latest -i nextjsScaling Considerations
Database
- Turso automatically scales reads
- Consider read replicas for high traffic
- Monitor query performance
Application
- Vercel auto-scales
- Docker: Use Kubernetes or Docker Swarm
- Self-hosted: Use load balancer with multiple instances
Caching
- React Query handles client-side caching
- Consider Redis for server-side caching
- Use CDN for static assets
Backup & Recovery
Database Backups
# Export database
turso db shell forge-production ".dump" > backup.sql
# Create point-in-time recovery
turso db tokens create forge-production --expiration 90dDisaster Recovery
- Keep database backups in separate region
- Document environment variables securely
- Use infrastructure-as-code (Terraform, Pulumi)
- Test recovery procedures regularly
Updating the Application
Zero-Downtime Deployment
Vercel and Railway handle this automatically. For self-hosted:
# Pull latest code
git pull origin main
# Install dependencies
pnpm install
# Run migrations
pnpm prisma migrate deploy
# Build
pnpm build
# Restart with PM2
pm2 reload forgeDatabase Migrations
Always run migrations before deploying new code:
# Check pending migrations
pnpm prisma migrate status
# Apply migrations
pnpm prisma migrate deployTroubleshooting
Build Errors
Prisma generate fails:
rm -rf node_modules/.prisma
pnpm prisma generateType errors:
pnpm typecheckRuntime Errors
Database connection fails:
- Verify
TURSO_DATABASE_URLformat - Check auth token hasn’t expired
- Ensure IP allowlist includes your server
Authentication fails:
- Verify Azure AD redirect URI matches exactly
- Check issuer URL format
- Regenerate client secret if expired
Performance Issues
Slow database queries:
# Check query performance
turso db shell forge-production "EXPLAIN QUERY PLAN SELECT * FROM ideas"High memory usage:
- Check for memory leaks in React components
- Monitor server-side caching
- Consider increasing server resources
Last updated on