Production Deployment

Step-by-step guide for deploying Smart Shelf to production environments with platform-specific instructions.

Production Deployment

Complete guide for deploying Smart Shelf to production environments, covering platform setup, configuration, and best practices.

Deployment Platforms

Vercel provides the optimal deployment experience for Next.js applications with automatic optimizations and global edge distribution.

Key Features:

  • Automatic Git-based deployments
  • Global Edge Network with 100+ locations
  • Automatic HTTPS with custom domains
  • Preview deployments for every branch
  • Built-in analytics and performance monitoring

Vercel Deployment Steps

1. Initial Setup

# Install Vercel CLI
npm install -g vercel

# Login to your Vercel account
vercel login

# Link your project
vercel link

2. Environment Configuration

# Add production environment variables
vercel env add NEXT_PUBLIC_SUPABASE_URL production
vercel env add NEXT_PUBLIC_SUPABASE_ANON_KEY production
vercel env add SUPABASE_SERVICE_ROLE_KEY production
vercel env add DATABASE_URL production

# Add staging environment variables
vercel env add NEXT_PUBLIC_APP_URL staging
vercel env add NODE_ENV staging

3. Deploy to Production

# Manual deployment
vercel --prod

# Automatic deployment via Git
git push origin main

4. Custom Domain Setup

  1. Add domain in Vercel dashboard: Settings > Domains
  2. Configure DNS records with your domain provider
  3. Verify domain ownership
  4. Automatic SSL certificate provisioning

DNS Configuration:

Type    Name    Value
A       @       76.76.19.61
CNAME   www     your-app.vercel.app

Alternative Platforms

Netlify

JAMstack deployment with excellent build performance and edge functions.

# Install Netlify CLI
npm install -g netlify-cli

# Login and deploy
netlify login
netlify build
netlify deploy --prod

netlify.toml Configuration:

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

[build.environment]
  NODE_VERSION = "18"

[[headers]]
  for = "/*"
  [headers.values]
    X-Frame-Options = "DENY"
    X-Content-Type-Options = "nosniff"

Railway

Container-based deployment with integrated database hosting.

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

# Login and deploy
railway login
railway link
railway up

railway.json Configuration:

{
  "build": {
    "builder": "NIXPACKS"
  },
  "deploy": {
    "startCommand": "npm start",
    "healthcheckPath": "/api/health"
  }
}

AWS Amplify

Full-stack deployment on AWS infrastructure.

# Install Amplify CLI
npm install -g @aws-amplify/cli

# Configure and deploy
amplify init
amplify add hosting
amplify publish

amplify.yml Configuration:

version: 1
applications:
  - frontend:
      phases:
        preBuild:
          commands:
            - npm ci
        build:
          commands:
            - npm run build
      artifacts:
        baseDirectory: .next
        files:
          - '**/*'
      cache:
        paths:
          - node_modules/**/*

Docker Deployment

Dockerfile:

FROM node:18-alpine AS base

# Install dependencies only when needed
FROM base AS deps
RUN apk add --no-cache libc6-compat
WORKDIR /app

COPY package.json package-lock.json* ./
RUN npm ci --only=production

# Rebuild the source code only when needed
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .

ENV NEXT_TELEMETRY_DISABLED 1
RUN npm run build

# Production image, copy all the files and run next
FROM base AS runner
WORKDIR /app

ENV NODE_ENV production
ENV NEXT_TELEMETRY_DISABLED 1

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 for Development:

version: '3.8'

services:
  app:
    build: .
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=production
      - NEXT_PUBLIC_SUPABASE_URL=${NEXT_PUBLIC_SUPABASE_URL}
      - NEXT_PUBLIC_SUPABASE_ANON_KEY=${NEXT_PUBLIC_SUPABASE_ANON_KEY}
    depends_on:
      - db

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

volumes:
  postgres_data:

Pre-Deployment Checklist

Code Quality Validation

  • All unit tests passing (npm run test)
  • Integration tests passing (npm run test:e2e)
  • TypeScript compilation successful (npx tsc --noEmit)
  • ESLint checks passed (npm run lint)
  • Prettier formatting applied (npm run format)
  • Security scan completed (npm audit)
  • Code review approved

Performance Validation

  • Lighthouse performance score > 90
  • Bundle size analysis completed (npm run analyze)
  • Core Web Vitals optimized
  • Image optimization verified
  • Database queries optimized
  • Caching strategy implemented

Security Validation

  • Environment variables secured
  • API endpoints protected
  • Authentication flow tested
  • Input validation implemented
  • SQL injection prevention verified
  • XSS protection enabled

Infrastructure Validation

  • SSL certificates configured
  • CDN configuration verified
  • Database migrations applied
  • Backup procedures tested
  • Monitoring systems configured
  • Error reporting enabled

CI/CD Pipeline

GitHub Actions Workflow

.github/workflows/deploy.yml:

name: Deploy to Production

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '18'
          cache: 'npm'
      
      - name: Install dependencies
        run: npm ci
      
      - name: Run tests
        run: npm run test
      
      - name: Run linting
        run: npm run lint
      
      - name: Build application
        run: npm run build

  deploy:
    needs: test
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'
    steps:
      - uses: actions/checkout@v4
      
      - name: Deploy to Vercel
        uses: amondnet/vercel-action@v25
        with:
          vercel-token: ${{ secrets.VERCEL_TOKEN }}
          github-token: ${{ secrets.GITHUB_TOKEN }}
          vercel-org-id: ${{ secrets.ORG_ID }}
          vercel-project-id: ${{ secrets.PROJECT_ID }}
          vercel-args: '--prod'

Deployment Environments

Development

  • Purpose: Feature development and testing
  • URL: http://localhost:3000
  • Database: Local Supabase instance
  • Features: Hot reloading, debug tools

Staging

  • Purpose: Pre-production testing
  • URL: https://staging.smartshelf.app
  • Database: Staging database with production-like data
  • Features: Production build, limited access

Production

  • Purpose: Live application
  • URL: https://smartshelf.app
  • Database: Production database
  • Features: Full optimization, monitoring, backups

Build Optimization

Next.js Configuration

next.config.mjs:

/** @type {import('next').NextConfig} */
const nextConfig = {
  experimental: {
    serverComponentsExternalPackages: ['@supabase/supabase-js'],
  },
  images: {
    domains: ['your-domain.com', 'supabase.co'],
    formats: ['image/webp', 'image/avif'],
    minimumCacheTTL: 31536000,
  },
  compiler: {
    removeConsole: process.env.NODE_ENV === 'production',
  },
  output: 'standalone',
  headers: async () => [
    {
      source: '/(.*)',
      headers: [
        {
          key: 'X-Frame-Options',
          value: 'DENY',
        },
        {
          key: 'X-Content-Type-Options',
          value: 'nosniff',
        },
        {
          key: 'Referrer-Policy',
          value: 'origin-when-cross-origin',
        },
      ],
    },
  ],
}

export default nextConfig

Bundle Analysis

# Analyze bundle size
npm run build
npm run analyze

# View bundle composition
npx webpack-bundle-analyzer .next/analyze/client.html

Performance Optimization

Code Splitting:

// Dynamic imports for large components
const AnalyticsPage = dynamic(() => import('./analytics'), {
  loading: () => <div>Loading analytics...</div>,
  ssr: false
})

// Lazy loading for non-critical features
const BarcodeScanner = lazy(() => import('@/components/barcode/scanner'))

Tree Shaking:

// Import only what you need
import { Button } from '@/components/ui/button' // ✅ Good
import * as UI from '@/components/ui' // ❌ Avoid

Health Checks

Application Health Check

app/api/health/route.ts:

import { NextResponse } from 'next/server'
import { createClient } from '@/lib/supabase/server'

export async function GET() {
  try {
    // Test database connection
    const supabase = createClient()
    const { error } = await supabase
      .from('products')
      .select('id')
      .limit(1)
    
    if (error) throw error

    return NextResponse.json({
      status: 'healthy',
      timestamp: new Date().toISOString(),
      database: 'connected',
      environment: process.env.NODE_ENV,
    })
  } catch (error) {
    return NextResponse.json(
      {
        status: 'unhealthy',
        timestamp: new Date().toISOString(),
        error: error instanceof Error ? error.message : 'Unknown error',
      },
      { status: 503 }
    )
  }
}

Monitoring Integration

Uptime Monitoring:

# Curl-based health check
curl -f https://your-domain.com/api/health

# Advanced health check script
#!/bin/bash
HEALTH_URL="https://your-domain.com/api/health"
RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" $HEALTH_URL)

if [ $RESPONSE -eq 200 ]; then
  echo "✅ Application is healthy"
  exit 0
else
  echo "❌ Application is unhealthy (HTTP $RESPONSE)"
  exit 1
fi

Rollback Procedures

Vercel Rollback

# List recent deployments
vercel ls

# Rollback to previous deployment
vercel rollback [deployment-url]

# Promote specific deployment
vercel promote [deployment-url] --scope=production

Database Rollback

-- Rollback database migration
BEGIN;
-- Your rollback SQL here
ROLLBACK; -- or COMMIT if successful

Emergency Procedures

  1. Immediate Rollback: Use platform-specific rollback commands
  2. Communication: Notify stakeholders of issues
  3. Investigation: Identify root cause
  4. Resolution: Implement fix and redeploy
  5. Post-Mortem: Document lessons learned