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:
- Visit vercel.com
- Click "New Project"
- Import your Git repository
- 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)
- Go to your project settings in Vercel
- Navigate to "Domains"
- Add your custom domain
- 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:
- Add PostgreSQL service in Railway dashboard
- Copy the connection string
- 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! 🚀