Skip to main content

Deployment Guide

This guide covers multiple deployment strategies for the Pet Service Management System.

Docker

Containerized deployment

Railway

One-click deployment with Railway MCP

Cloud Platforms

AWS, GCP, Vercel

Docker Deployment

Prerequisites

  • Docker 20.10+
  • Docker Compose 2.0+

Step 1: Build Docker Images

Create a Dockerfile in the root directory:
# backend/Dockerfile
FROM node:18-alpine AS builder

WORKDIR /app

# Copy package files
COPY package*.json ./
COPY prisma ./prisma/

# Install dependencies
RUN npm ci

# Copy source code
COPY . .

# Generate Prisma client
RUN npx prisma generate

# Build application
RUN npm run build

# Production stage
FROM node:18-alpine

WORKDIR /app

# Copy built files
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/prisma ./prisma
COPY --from=builder /app/package*.json ./

# Expose port
EXPOSE 3001

# Start application
CMD ["npm", "run", "start:prod"]

Step 2: Docker Compose Configuration

Create docker-compose.yml in the root directory:
docker-compose.yml
version: '3.8'

services:
  postgres:
    image: postgres:15-alpine
    container_name: petservice-db
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
      POSTGRES_DB: petservice
    volumes:
      - postgres_data:/var/lib/postgresql/data
    ports:
      - "5432:5432"
    networks:
      - petservice-network
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      timeout: 5s
      retries: 5

  backend:
    build:
      context: ./backend
      dockerfile: Dockerfile
    container_name: petservice-backend
    environment:
      NODE_ENV: production
      PORT: 3001
      DATABASE_URL: postgresql://postgres:postgres@postgres:5432/petservice
      BETTER_AUTH_URL: http://backend:3001/api/auth
      BETTER_AUTH_SECRET: ${BETTER_AUTH_SECRET}
      SESSION_SECRET: ${SESSION_SECRET}
      JWT_SECRET: ${JWT_SECRET}
      FRONTEND_URL: http://frontend:3000
    ports:
      - "3001:3001"
    depends_on:
      postgres:
        condition: service_healthy
    networks:
      - petservice-network
    command: >
      sh -c "npx prisma migrate deploy &&
             npm run start:prod"

  frontend:
    build:
      context: ./frontend
      dockerfile: Dockerfile
    container_name: petservice-frontend
    environment:
      NEXT_PUBLIC_API_URL: http://localhost:3001
      NEXT_PUBLIC_APP_URL: http://localhost:3000
    ports:
      - "3000:3000"
    depends_on:
      - backend
    networks:
      - petservice-network

volumes:
  postgres_data:

networks:
  petservice-network:
    driver: bridge

Step 3: Environment Configuration

Create .env file in the root directory:
.env
# Secrets (Generate with: openssl rand -base64 32)
BETTER_AUTH_SECRET=your-32-char-secret-here
SESSION_SECRET=your-32-char-secret-here
JWT_SECRET=your-32-char-secret-here

# Database
POSTGRES_USER=postgres
POSTGRES_PASSWORD=postgres
POSTGRES_DB=petservice
Security: Never commit .env to version control. Use .env.example as template.

Step 4: Build and Run

1

Build Images

docker-compose build
2

Start Services

docker-compose up -d
3

Verify Services

# Check running containers
docker-compose ps

# View logs
docker-compose logs -f backend
docker-compose logs -f frontend
4

Access Application

  • Frontend: http://localhost:3000
  • Backend API: http://localhost:3001
  • Prisma Studio: docker-compose exec backend npx prisma studio

Docker Management Commands

docker-compose up -d

Railway Deployment

Railway provides automatic deployments with built-in PostgreSQL and zero-config setup.

Option 1: Deploy via Railway CLI

1

Install Railway CLI

npm install -g @railway/cli
2

Login to Railway

railway login
3

Initialize Project

railway init
4

Add PostgreSQL Database

railway add postgresql
Railway automatically sets DATABASE_URL environment variable.
5

Set Environment Variables

railway variables set BETTER_AUTH_SECRET=$(openssl rand -base64 32)
railway variables set SESSION_SECRET=$(openssl rand -base64 32)
railway variables set JWT_SECRET=$(openssl rand -base64 32)
railway variables set NODE_ENV=production
railway variables set FRONTEND_URL=https://your-app.railway.app
6

Deploy Backend

cd backend
railway up
7

Deploy Frontend

cd frontend
railway up
8

Run Migrations

railway run npx prisma migrate deploy

Option 2: Deploy via Railway Button

Deploy to Railway

Click to deploy with one button
  1. Click “Deploy on Railway” button
  2. Connect your GitHub repository
  3. Railway auto-detects backend/frontend
  4. Add PostgreSQL database from Railway marketplace
  5. Set environment variables in Railway dashboard
  6. Deploy automatically on git push

Railway Environment Variables

Set these in Railway dashboard or CLI:
VariableValueNotes
NODE_ENVproductionEnvironment mode
DATABASE_URLAuto-set by RailwayPostgreSQL connection
BETTER_AUTH_SECRETGenerate 32+ charsAuth secret
SESSION_SECRETGenerate 32+ charsSession encryption
JWT_SECRETGenerate 32+ charsJWT signing
FRONTEND_URLhttps://your-app.railway.appFrontend URL
PORT3001 (backend)Service port

Railway MCP Integration

Railway MCP (Model Context Protocol) enables AI assistants to manage your deployments.
Configure Railway MCP:
  1. Install Railway MCP server:
npm install -g @railway/mcp
  1. Configure in your Claude Code settings:
{
  "mcpServers": {
    "railway": {
      "command": "railway-mcp",
      "env": {
        "RAILWAY_TOKEN": "your-railway-token"
      }
    }
  }
}
  1. Use AI commands:
Claude: "Deploy backend to Railway"
Claude: "Check Railway deployment status"
Claude: "View Railway logs for backend service"
Claude: "Add PostgreSQL to Railway project"

Cloud Platform Deployment

Vercel (Frontend)

1

Install Vercel CLI

npm install -g vercel
2

Deploy Frontend

cd frontend
vercel
3

Set Environment Variables

vercel env add NEXT_PUBLIC_API_URL
vercel env add NEXT_PUBLIC_APP_URL
4

Production Deployment

vercel --prod

Heroku (Backend)

1

Install Heroku CLI

brew install heroku/brew/heroku
2

Create Heroku App

cd backend
heroku create petservice-backend
3

Add PostgreSQL

heroku addons:create heroku-postgresql:mini
4

Set Environment Variables

heroku config:set BETTER_AUTH_SECRET=$(openssl rand -base64 32)
heroku config:set SESSION_SECRET=$(openssl rand -base64 32)
heroku config:set JWT_SECRET=$(openssl rand -base64 32)
heroku config:set NODE_ENV=production
5

Deploy

git push heroku main
6

Run Migrations

heroku run npx prisma migrate deploy

AWS (Full Stack)

# Build frontend
cd frontend
npm run build

# Deploy to S3
aws s3 sync .next/static s3://your-bucket/static
aws cloudfront create-invalidation --distribution-id XXX --paths "/*"

Production Checklist

  • HTTPS/TLS enabled (use Let’s Encrypt or cloud provider SSL)
  • Strong secrets (32+ characters, randomly generated)
  • Environment variables properly set (no hardcoded secrets)
  • CORS configured for specific origins
  • Rate limiting enabled on API endpoints
  • Database backups configured (daily/hourly)
  • Security headers configured (Helmet.js)
  • CDN configured for static assets
  • Database connection pooling enabled
  • Query optimization with proper indexes
  • Caching strategy implemented (Redis optional)
  • Image optimization enabled
  • Gzip compression enabled
  • Application logging configured
  • Error tracking (Sentry, LogRocket)
  • Uptime monitoring (UptimeRobot, Pingdom)
  • Performance monitoring (New Relic, DataDog)
  • Database monitoring (pgAdmin, Railway analytics)
  • Production database created
  • Migrations applied: npx prisma migrate deploy
  • Seed data loaded (if needed)
  • Backup strategy configured
  • Connection pool configured
  • Indexes optimized
  • NODE_ENV=production set
  • All required environment variables configured
  • Frontend API URL points to production backend
  • Backend CORS allows production frontend
  • Email service configured (SMTP credentials)

Continuous Deployment

GitHub Actions

Create .github/workflows/deploy.yml:
name: Deploy to Production

on:
  push:
    branches: [main]

jobs:
  deploy-backend:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: 18

      - name: Install dependencies
        working-directory: backend
        run: npm ci

      - name: Build
        working-directory: backend
        run: npm run build

      - name: Deploy to Railway
        run: |
          npm install -g @railway/cli
          railway up --service backend
        env:
          RAILWAY_TOKEN: ${{ secrets.RAILWAY_TOKEN }}

  deploy-frontend:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: 18

      - name: Install dependencies
        working-directory: frontend
        run: npm ci

      - name: Build
        working-directory: frontend
        run: npm run build

      - name: Deploy to Vercel
        run: vercel --prod --token ${{ secrets.VERCEL_TOKEN }}

Monitoring & Maintenance

Health Checks

# Backend health
curl https://api.yourapp.com/health

# Database connection
curl https://api.yourapp.com/db/health

# Frontend
curl https://yourapp.com

View Logs

docker-compose logs -f backend
docker-compose logs -f frontend

Database Backup

# PostgreSQL dump
pg_dump -h localhost -U postgres petservice > backup.sql

# Restore
psql -h localhost -U postgres petservice < backup.sql

Troubleshooting

Solution:
  • Check build logs: railway logs or docker-compose logs
  • Verify environment variables are set
  • Ensure dependencies are installed: npm ci
  • Check Dockerfile syntax
Solution:
  • Verify DATABASE_URL is correct
  • Check database is running
  • Confirm firewall rules allow connection
  • Test connection: psql $DATABASE_URL
Solution:
  • Set FRONTEND_URL in backend environment
  • Verify CORS configuration in main.ts
  • Check frontend uses correct API URL
Solution:
  • Use Railway/Vercel automatic SSL
  • For custom domains, configure SSL certificate
  • Use Let’s Encrypt for free SSL: certbot

Next Steps


Deployment Complete! Your Pet Service Management System is now live.