Files
tt-booking/docs/DEPLOYMENT_GUIDE.md

12 KiB

Deployment Strategy for Table Tennis Booking System

Overview

This document outlines comprehensive deployment strategies for the Table Tennis Booking System, considering both self-hosting and cloud deployment options. The application is a Next.js-based system with SQLite database, designed for production use.

1. Self-Hosting Strategy

Architecture:

Internet → Cloudflare → Cloudflare Tunnel → Raspberry Pi → Docker Container

Requirements:

  • Raspberry Pi 4 (4GB+ RAM recommended)
  • Stable internet connection
  • Cloudflare account (free tier sufficient)
  • Domain name (can be managed through Cloudflare)

Setup Steps:

  1. Raspberry Pi Preparation

    # Update system
    sudo apt update && sudo apt upgrade -y
    
    # Install Docker
    curl -fsSL https://get.docker.com -o get-docker.sh
    sudo sh get-docker.sh
    sudo usermod -aG docker $USER
    
    # Install Docker Compose
    sudo apt install docker-compose -y
    
  2. Application Deployment

    # Clone repository
    git clone <your-repo-url>
    cd tt-booking
    
    # Create production environment file
    cp .env.example .env.production
    # Edit .env.production with your values
    
    # Deploy with Docker
    docker-compose -f docker-compose.production.yml up -d
    
  3. Cloudflare Tunnel Setup

    # Install cloudflared
    wget https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-arm64.deb
    sudo dpkg -i cloudflared-linux-arm64.deb
    
    # Authenticate
    cloudflared tunnel login
    
    # Create tunnel
    cloudflared tunnel create tt-booking
    
    # Configure tunnel (create config.yml)
    cloudflared tunnel route dns tt-booking yourdomain.com
    
    # Run tunnel
    cloudflared tunnel run tt-booking
    

Cloudflare Tunnel Config (~/.cloudflared/config.yml):

tunnel: <tunnel-id>
credentials-file: /home/pi/.cloudflared/<tunnel-id>.json

ingress:
    - hostname: yourdomain.com
      service: http://localhost:3000
    - service: http_status:404

Production Docker Compose (docker-compose.production.yml):

version: '3.8'

services:
    tt-booking:
        build: .
        ports:
            - '3000:3000'
        environment:
            - NODE_ENV=production
            - DATABASE_URL=/app/data/sqlite.db
            - NEXTAUTH_URL=https://yourdomain.com
            - NEXTAUTH_SECRET=${NEXTAUTH_SECRET}
            - EMAIL_USER=${EMAIL_USER}
            - EMAIL_PASSWORD=${EMAIL_PASSWORD}
            - ADMIN_EMAIL=${ADMIN_EMAIL}
            - ADMIN_PASSWORD=${ADMIN_PASSWORD}
        volumes:
            - ./data:/app/data
            - ./backups:/app/backups
        restart: unless-stopped
        healthcheck:
            test: ['CMD', 'curl', '-f', 'http://localhost:3000/api/health']
            interval: 30s
            timeout: 10s
            retries: 3

    # Backup service
    backup:
        image: alpine:latest
        volumes:
            - ./data:/data:ro
            - ./backups:/backups
        command: >
            sh -c "
            while true; do
              cp /data/sqlite.db /backups/sqlite-$(date +%Y%m%d-%H%M%S).db
              find /backups -name 'sqlite-*.db' -mtime +7 -delete
              sleep 86400
            done"
        restart: unless-stopped

Advantages:

  • No need for port forwarding or exposing home IP
  • Free SSL certificates through Cloudflare
  • DDoS protection and CDN benefits
  • Easy domain management
  • Cost-effective (only domain cost ~$10-15/year)

Disadvantages:

  • Dependent on home internet stability
  • Limited by residential bandwidth
  • Requires basic Linux administration skills

Option B: Traditional Self-Hosting with Reverse Proxy

Architecture:

Internet → Router/Firewall → Nginx → Docker Container

Requirements:

  • Dedicated server or powerful Raspberry Pi
  • Static IP address or Dynamic DNS service
  • SSL certificate (Let's Encrypt)
  • Port forwarding configuration

Setup includes all the Docker setup above, plus:

  1. Nginx Configuration

    # Install Nginx
    sudo apt install nginx certbot python3-certbot-nginx
    
    # Configure SSL
    sudo certbot --nginx -d yourdomain.com
    
  2. Updated Docker Compose with Nginx Use the existing docker-compose.yml with Nginx service.

Advantages:

  • Full control over infrastructure
  • No dependency on third-party tunneling services
  • Better performance for local network access

Disadvantages:

  • Requires static IP or Dynamic DNS
  • More complex firewall/security configuration
  • SSL certificate management overhead

2. Cloud Deployment Strategies

Cost Estimate: $12-25/month

Features:

  • Automatic deployments from Git
  • Built-in SSL certificates
  • Automatic scaling
  • Integrated monitoring

Deployment:

  1. Connect GitHub repository
  2. Configure environment variables
  3. Add persistent volume for SQLite database
  4. Deploy with zero-config

Configuration:

# .do/app.yaml
name: tt-booking
services:
    - name: web
      source_dir: /
      github:
          repo: your-username/tt-booking
          branch: main
      run_command: npm start
      environment_slug: node-js
      instance_count: 1
      instance_size_slug: basic-xxs
      envs:
          - key: NODE_ENV
            value: production
          - key: DATABASE_URL
            value: /app/data/sqlite.db

Option B: Railway (Developer-Friendly)

Cost Estimate: $5-20/month

Features:

  • Git-based deployments
  • Built-in databases available
  • Simple pricing model
  • Excellent developer experience

Deployment:

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

# Login and deploy
railway login
railway init
railway up

Option C: Vercel + PlanetScale (Serverless)

Cost Estimate: $0-20/month (depending on usage)

Modifications needed:

  • Replace SQLite with PlanetScale MySQL
  • Update database schema for MySQL compatibility
  • Modify connection configuration

Deployment:

# Install Vercel CLI
npm install -g vercel

# Deploy
vercel --prod

Option D: AWS/GCP/Azure (Enterprise Scale)

Cost Estimate: $30-100+/month

AWS Deployment Options:

  1. ECS Fargate + RDS

    • Container-based deployment
    • Managed database
    • Auto-scaling capabilities
  2. Elastic Beanstalk

    • Simple deployment model
    • Built-in monitoring
    • Easy environment management
  3. App Runner

    • Serverless container platform
    • Automatic scaling
    • Pay-per-use pricing

3. Database Considerations

For Self-Hosting

  • SQLite: Perfect for small to medium loads
  • Backup Strategy: Automated daily backups to external storage
  • Monitoring: Simple file-based health checks

For Cloud Deployment

  • Small Scale: Keep SQLite with persistent volumes
  • Medium Scale: PostgreSQL (Railway, DigitalOcean Managed DB)
  • Large Scale: Multi-region database (AWS RDS, Google Cloud SQL)

4. Monitoring and Maintenance

Essential Monitoring

# Add to crontab for health checks
*/5 * * * * curl -f https://yourdomain.com/api/health || echo "App down" | mail -s "Alert" admin@example.com

Backup Strategy

  1. Database Backups: Daily automated SQLite file copies
  2. Environment Config: Version controlled .env files
  3. Application Code: Git-based source control

Update Strategy

#!/bin/bash
# update.sh
cd /path/to/tt-booking
git pull origin main
docker-compose -f docker-compose.production.yml down
docker-compose -f docker-compose.production.yml up -d --build

5. Security Considerations

Self-Hosting Security Checklist

  • Firewall configured (only necessary ports open)
  • Regular OS updates automated
  • Non-root user for application
  • SSL certificates properly configured
  • Database backups encrypted
  • Rate limiting configured (already in nginx.conf)
  • Log monitoring for suspicious activity

Cloud Security

  • Environment variables properly secured
  • Database access restricted
  • API rate limiting enabled
  • Regular dependency updates
  • Security headers configured (already in app)

6. Cost Comparison

Deployment Method Monthly Cost Effort Scalability Reliability
Raspberry Pi + CF Tunnel $1-2 Medium Low Medium
Traditional Self-Host $5-10 High Low Medium
DigitalOcean App Platform $12-25 Low Medium High
Railway $5-20 Very Low Medium High
Vercel + PlanetScale $0-20 Low High High
AWS/GCP/Azure $30-100+ High Very High Very High

For Personal/Small Group Use:

Raspberry Pi + Cloudflare Tunnel - Most cost-effective with good reliability

For Small Business:

Railway or DigitalOcean App Platform - Balance of simplicity and reliability

For Enterprise:

AWS/GCP with proper CI/CD pipeline - Maximum scalability and reliability

8. Local Development Best Practices

Standalone Development

# Quick development setup
npm install
npm run dev

Docker Development

# Development with Docker
docker-compose up -d

Production-like Local Testing

# Test production build locally
npm run build
npm start

9. Health Check Endpoint

The application includes a health check endpoint at /api/health for monitoring purposes. You should create this endpoint:

// app/api/health/route.ts
import { NextResponse } from 'next/server';
import { db } from '@/lib/db';

export async function GET() {
	try {
		// Basic database connectivity check
		await db.select().from(settings).limit(1);

		return NextResponse.json({
			status: 'healthy',
			timestamp: new Date().toISOString(),
			uptime: process.uptime(),
		});
	} catch (error) {
		return NextResponse.json({ status: 'unhealthy', error: 'Database connection failed' }, { status: 500 });
	}
}

10. Environment Variables for Production

Create a .env.production file with the following required variables:

# Application
NODE_ENV=production
NEXTAUTH_URL=https://yourdomain.com
NEXTAUTH_SECRET=your-very-long-random-secret-here

# Database
DATABASE_URL=/app/data/sqlite.db

# Email Configuration (optional)
EMAIL_USER=your-email@gmail.com
EMAIL_PASSWORD=your-app-specific-password

# Admin Account
ADMIN_EMAIL=admin@yourdomain.com
ADMIN_PASSWORD=secure-admin-password

# Optional: Rate limiting
RATE_LIMIT_MAX=100
RATE_LIMIT_WINDOW=900000

11. Docker Production Optimization

Create a production-optimized Dockerfile.production:

FROM node:18-alpine AS base

# Install dependencies only when needed
FROM base AS deps
WORKDIR /app
COPY package.json package-lock.json* ./
RUN npm ci --only=production && npm cache clean --force

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

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

ENV NODE_ENV production

RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs

# Copy built application
COPY --from=builder --chown=nextjs:nodejs /app/.next ./.next
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./package.json
COPY --from=builder /app/public ./public

# Create data directory for SQLite
RUN mkdir -p /app/data && chown nextjs:nodejs /app/data

USER nextjs

EXPOSE 3000

ENV PORT 3000
ENV HOSTNAME "0.0.0.0"

CMD ["npm", "start"]

This deployment strategy provides multiple pathways depending on your technical expertise, budget, and scaling requirements. The Cloudflare Tunnel approach is particularly attractive for self-hosting as it eliminates many traditional networking complexities while maintaining security and reliability.