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
Option A: Raspberry Pi + Cloudflare Tunnel (Recommended)
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:
-
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 -
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 -
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:
-
Nginx Configuration
# Install Nginx sudo apt install nginx certbot python3-certbot-nginx # Configure SSL sudo certbot --nginx -d yourdomain.com -
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
Option A: DigitalOcean App Platform (Recommended for Small Scale)
Cost Estimate: $12-25/month
Features:
- Automatic deployments from Git
- Built-in SSL certificates
- Automatic scaling
- Integrated monitoring
Deployment:
- Connect GitHub repository
- Configure environment variables
- Add persistent volume for SQLite database
- 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:
-
ECS Fargate + RDS
- Container-based deployment
- Managed database
- Auto-scaling capabilities
-
Elastic Beanstalk
- Simple deployment model
- Built-in monitoring
- Easy environment management
-
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
- Database Backups: Daily automated SQLite file copies
- Environment Config: Version controlled
.envfiles - 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 |
7. Recommended Approach
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.