Skip to Content
WebForge Web - Deployment Guide

Forge Web - Deployment Guide

This guide covers deploying the Forge web application to various hosting platforms.


Prerequisites

Required Accounts

ServicePurposeRequired
TursoDatabase hostingYes
Azure ADAuthenticationYes
LiveKit CloudVoice/video callingOptional
Vercel/Railway/etc.App hostingYes

Required Tools

ToolVersionPurpose
Node.js18+Runtime
pnpm8+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 32

External 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-token

Initialize Schema

The schema is automatically applied when you run:

npx prisma db push

2. Azure AD (Microsoft Entra ID)

Register Application

  1. Go to Azure Portal 
  2. Navigate to Azure Active DirectoryApp registrations
  3. Click New registration
  4. 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

  1. Go to Authentication
  2. Add redirect URI for your production domain
  3. Enable ID tokens under Implicit grant

Create Client Secret

  1. Go to Certificates & secrets
  2. Click New client secret
  3. Set expiration and create
  4. Copy the secret value immediately (shown only once)

Note Your Credentials

  • Application (client) IDAUTH_MICROSOFT_ENTRA_ID_ID
  • Directory (tenant) ID → Use in issuer URL
  • Client secret valueAUTH_MICROSOFT_ENTRA_ID_SECRET

3. LiveKit Cloud (Optional)

  1. Sign up at LiveKit Cloud 
  2. Create a new project
  3. Go to SettingsKeys
  4. Note your:
    • URLLIVEKIT_URL
    • API KeyLIVEKIT_API_KEY
    • API SecretLIVEKIT_API_SECRET

Deployment Options

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 --prod

Deploy via GitHub

  1. Push your code to GitHub
  2. Go to vercel.com 
  3. Click Import Project
  4. Select your GitHub repository
  5. Configure environment variables
  6. Click Deploy

Custom Domain

  1. Go to your project in Vercel
  2. Navigate to SettingsDomains
  3. Add your custom domain
  4. Update DNS records as instructed
  5. Update NEXT_PUBLIC_APP_URL to your domain
  6. 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 up

Option 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-web

Option 4: Self-Hosted (Node.js)

Build

# Install dependencies pnpm install # Generate Prisma client pnpm prisma generate # Build application pnpm build

Run 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 startup

Nginx 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 push

Production

# Generate migration files pnpm prisma migrate dev --name your_migration_name # Apply migrations in production pnpm prisma migrate deploy

Seeding (Optional)

# Run seed script pnpm prisma db seed

Post-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 nextjs

Scaling 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 90d

Disaster Recovery

  1. Keep database backups in separate region
  2. Document environment variables securely
  3. Use infrastructure-as-code (Terraform, Pulumi)
  4. 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 forge

Database Migrations

Always run migrations before deploying new code:

# Check pending migrations pnpm prisma migrate status # Apply migrations pnpm prisma migrate deploy

Troubleshooting

Build Errors

Prisma generate fails:

rm -rf node_modules/.prisma pnpm prisma generate

Type errors:

pnpm typecheck

Runtime Errors

Database connection fails:

  • Verify TURSO_DATABASE_URL format
  • 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