Orchestra 9/Documentation

Deployment Guide 🚀

Deploy your Qmatic Canvas application to production with these comprehensive guides for popular hosting platforms.

🌐 Platform Options


🚀 Vercel Deployment (Recommended)

Vercel provides the best experience for Next.js applications with zero configuration required.

Prerequisites

  • GitHub, GitLab, or Bitbucket account
  • Your code pushed to a repository
  • Environment variables ready

Step-by-Step Deployment

1. Connect Your Repository

# Install Vercel CLI (optional)
npm i -g vercel

# Login to Vercel
vercel login

# Deploy from your project directory
vercel

Or use the Vercel Dashboard:

  1. Visit vercel.com
  2. Click "New Project"
  3. Import your Git repository
  4. Vercel auto-detects Next.js configuration

2. Configure Environment Variables

In your Vercel dashboard, add these environment variables:

# Database
DATABASE_URL=postgresql://username:password@host:port/database

# Authentication
BETTER_AUTH_SECRET=your-super-secret-key-here
BETTER_AUTH_URL=https://your-domain.vercel.app

# OAuth Providers
GOOGLE_CLIENT_ID=your-google-client-id
GOOGLE_CLIENT_SECRET=your-google-client-secret
GITHUB_CLIENT_ID=your-github-client-id
GITHUB_CLIENT_SECRET=your-github-client-secret

# Email Service
RESEND_API_KEY=your-resend-api-key

3. Database Migration

Run database migrations after deployment:

# Using Vercel CLI
vercel env pull .env.local
pnpm run db:push

4. Custom Domain (Optional)

  1. Go to your project settings in Vercel
  2. Navigate to "Domains"
  3. Add your custom domain
  4. Update DNS records as instructed

Vercel Configuration

Create vercel.json for advanced configuration:

{
  "framework": "nextjs",
  "buildCommand": "pnpm run build",
  "devCommand": "pnpm run dev",
  "installCommand": "pnpm install",
  "functions": {
    "src/app/api/**": {
      "maxDuration": 30
    }
  },
  "crons": [
    {
      "path": "/api/cleanup",
      "schedule": "0 0 * * *"
    }
  ]
}

🌊 Netlify Deployment

Great alternative with excellent static hosting and serverless functions.

Deploy Process

1. Build Configuration

Create netlify.toml:

[build]
  command = "pnpm run build"
  publish = ".next"

[build.environment]
  NODE_VERSION = "18"
  NPM_FLAGS = "--prefer-offline --no-audit"

[[plugins]]
  package = "@netlify/plugin-nextjs"

[dev]
  command = "pnpm run dev"
  port = 3000

# Redirect rules for SPA routing
[[redirects]]
  from = "/docs/*"
  to = "/docs/:splat"
  status = 200

[[redirects]]
  from = "/dashboard/*"
  to = "/dashboard/:splat" 
  status = 200

2. Environment Variables

In Netlify dashboard → Site settings → Environment variables:

DATABASE_URL=your-database-url
BETTER_AUTH_SECRET=your-secret
BETTER_AUTH_URL=https://your-site.netlify.app
GOOGLE_CLIENT_ID=your-google-id
GOOGLE_CLIENT_SECRET=your-google-secret
GITHUB_CLIENT_ID=your-github-id
GITHUB_CLIENT_SECRET=your-github-secret
RESEND_API_KEY=your-resend-key

🚂 Railway Deployment

Full-stack platform with integrated database hosting.

Deployment Steps

1. Railway Setup

# Install Railway CLI
npm install -g @railway/cli

# Login and initialize
railway login
railway init

# Deploy
railway up

2. Database Setup

Railway can provide a PostgreSQL database:

  1. Add PostgreSQL service in Railway dashboard
  2. Copy the connection string
  3. Add to environment variables

3. Environment Configuration

# Railway automatically provides DATABASE_URL
# Add other variables in dashboard:

BETTER_AUTH_SECRET=generate-new-secret
BETTER_AUTH_URL=${{RAILWAY_PUBLIC_DOMAIN}}
GOOGLE_CLIENT_ID=your-google-client-id
GOOGLE_CLIENT_SECRET=your-google-client-secret
GITHUB_CLIENT_ID=your-github-client-id  
GITHUB_CLIENT_SECRET=your-github-client-secret
RESEND_API_KEY=your-resend-api-key

🐳 Docker Deployment

For custom hosting or container orchestration.

Dockerfile

FROM node:18-alpine AS deps
RUN apk add --no-cache libc6-compat
WORKDIR /app

# Install pnpm
RUN npm install -g pnpm

# Install dependencies
COPY package.json pnpm-lock.yaml ./
RUN pnpm install --frozen-lockfile

# Build stage
FROM node:18-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .

RUN npm install -g pnpm
RUN pnpm run build

# Production stage
FROM node:18-alpine AS runner
WORKDIR /app

ENV NODE_ENV production

# Create user
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs

# Copy built application
COPY --from=builder /app/public ./public
COPY --from=builder /app/.next/standalone ./
COPY --from=builder /app/.next/static ./.next/static

USER nextjs

EXPOSE 3000
ENV PORT 3000

CMD ["node", "server.js"]

Docker Compose

version: '3.8'

services:
  app:
    build: .
    ports:
      - "3000:3000"
    environment:
      - DATABASE_URL=postgresql://postgres:password@db:5432/qmatic_canvas
      - BETTER_AUTH_SECRET=your-secret-key
      - BETTER_AUTH_URL=http://localhost:3000
    depends_on:
      - db

  db:
    image: postgres:15
    environment:
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=password
      - POSTGRES_DB=qmatic_canvas
    volumes:
      - postgres_data:/var/lib/postgresql/data
    ports:
      - "5432:5432"

volumes:
  postgres_data:

⚙️ Production Optimization

Performance Checklist

  • [ ] Image Optimization: Use Next.js Image component
  • [ ] Bundle Analysis: Run pnpm run build:analyze
  • [ ] Database Indexes: Optimize frequent queries
  • [ ] Caching: Implement Redis for session storage
  • [ ] CDN: Use Vercel Edge Network or CloudFront
  • [ ] Monitoring: Set up error tracking (Sentry)

Security Hardening

// next.config.js security headers
const securityHeaders = [
  {
    key: 'X-DNS-Prefetch-Control',
    value: 'on'
  },
  {
    key: 'Strict-Transport-Security',
    value: 'max-age=63072000; includeSubDomains; preload'
  },
  {
    key: 'X-Frame-Options',
    value: 'DENY'
  },
  {
    key: 'X-Content-Type-Options',
    value: 'nosniff'
  },
  {
    key: 'Referrer-Policy',
    value: 'origin-when-cross-origin'
  }
]

module.exports = {
  async headers() {
    return [
      {
        source: '/(.*)',
        headers: securityHeaders,
      },
    ]
  },
}

Environment-Specific Configuration

// lib/config.ts
const config = {
  development: {
    apiUrl: 'http://localhost:3000/api',
    logLevel: 'debug',
    enableAnalytics: false
  },
  production: {
    apiUrl: 'https://your-domain.com/api',
    logLevel: 'error',
    enableAnalytics: true
  }
}

export default config[process.env.NODE_ENV || 'development']

🔍 Monitoring & Analytics

Health Checks

Create an API endpoint for monitoring:

// pages/api/health.ts
export default function handler(req: NextApiRequest, res: NextApiResponse) {
  // Check database connection
  // Check external services
  // Return status
  
  res.status(200).json({
    status: 'healthy',
    timestamp: new Date().toISOString(),
    version: process.env.npm_package_version
  })
}

Error Tracking

# Install Sentry
pnpm add @sentry/nextjs

# Configure in sentry.client.config.js
import * as Sentry from '@sentry/nextjs'

Sentry.init({
  dsn: process.env.SENTRY_DSN,
  environment: process.env.NODE_ENV,
})

🚨 Troubleshooting

Common Issues

Build Failures

# Clear Next.js cache
rm -rf .next
pnpm run build

# Check node version
node --version  # Should be 18+

Database Connection Issues

# Test database connection
npx drizzle-kit introspect:pg --connectionString="your-db-url"

# Run migrations
pnpm run db:push

Environment Variable Problems

  • Ensure all required variables are set
  • Check for typos in variable names
  • Verify OAuth callback URLs match deployment domain

Support Resources


Ready to deploy? Choose your platform and follow the guide above! 🚀