# SEEN - Production Deployment Guide

This guide walks you through deploying SEEN to production with proper security and reliability.

## Prerequisites

- Docker and Docker Compose installed
- Domain name (optional, for HTTPS)
- Server with at least:
  - 2 CPU cores
  - 4GB RAM
  - 20GB disk space
  - Ubuntu 22.04 or similar Linux distribution

## Quick Start (Development)

```bash
# Clone the repository
git clone <repository-url>
cd seen

# Start all services
docker compose up -d

# Access the application
# Frontend: http://localhost:8080
# Backend API: http://localhost:8081
```

## Production Deployment

### Step 1: Generate Secrets

```bash
# Generate strong secrets for production
./scripts/generate-secrets.sh

# This will output:
# - JWT secret
# - Database password
# - Cache password
# - Session secret
```

### Step 2: Configure Environment

```bash
# Copy production environment template
cp backend/.env.production backend/.env.production.local

# Edit the file and replace placeholders:
nano backend/.env.production.local
```

Required changes:
- `SEEN_AUTH_JWT_SECRET` - Use generated JWT secret
- `POSTGRES_PASSWORD` - Use generated database password
- `SEEN_TMDB_API_KEY` - Get from https://www.themoviedb.org/settings/api
- `SEEN_IGDB_CLIENT_ID` - Get from https://dev.twitch.tv/console/apps
- `SEEN_IGDB_CLIENT_SECRET` - Get from https://dev.twitch.tv/console/apps
- `SEEN_CORS_ALLOWED_ORIGINS` - Your domain (e.g., https://seen.yourdomain.com)

### Step 3: Update Docker Compose

```bash
# Edit docker-compose.prod.yml
nano docker-compose.prod.yml

# Update POSTGRES_PASSWORD environment variable
# Replace CHANGE_ME_STRONG_PASSWORD with your generated password
```

### Step 4: Deploy

```bash
# Build and start services
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d --build

# Check service status
docker compose ps

# View logs
docker compose logs -f
```

### Step 5: Verify Deployment

```bash
# Check health endpoints
curl http://localhost:8081/api/v1/health/live
curl http://localhost:8081/api/v1/health/ready

# Check frontend
curl http://localhost:8080/health

# Test API
curl http://localhost:8081/api/v1/dashboard
```

## HTTPS Setup (Recommended)

### Option 1: Using Caddy (Easiest)

Create `Caddyfile`:

```
seen.yourdomain.com {
    reverse_proxy localhost:8080
    
    # Automatic HTTPS with Let's Encrypt
    tls your-email@example.com
}

api.seen.yourdomain.com {
    reverse_proxy localhost:8081
    
    tls your-email@example.com
}
```

Run Caddy:

```bash
docker run -d \
  --name caddy \
  --network host \
  -v $PWD/Caddyfile:/etc/caddy/Caddyfile \
  -v caddy_data:/data \
  -v caddy_config:/config \
  caddy:latest
```

### Option 2: Using Nginx + Certbot

```bash
# Install Certbot
sudo apt install certbot python3-certbot-nginx

# Get SSL certificate
sudo certbot --nginx -d seen.yourdomain.com

# Nginx will be configured automatically
```

### Option 3: Using Traefik

Create `docker-compose.traefik.yml`:

```yaml
services:
  traefik:
    image: traefik:v2.10
    command:
      - "--providers.docker=true"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
      - "--certificatesresolvers.letsencrypt.acme.email=your-email@example.com"
      - "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"
      - "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web"
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./letsencrypt:/letsencrypt
    networks:
      - seen-network

  seen-frontend:
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.frontend.rule=Host(`seen.yourdomain.com`)"
      - "traefik.http.routers.frontend.entrypoints=websecure"
      - "traefik.http.routers.frontend.tls.certresolver=letsencrypt"
```

## Backup Configuration

### Automated Daily Backups

Backups run automatically every 24 hours when using `docker-compose.prod.yml`.

```bash
# View backup logs
docker logs seen-backup

# List backups
ls -lh backups/

# Backup retention: 7 days (configurable via BACKUP_RETENTION_DAYS)
```

### Manual Backup

```bash
# Create immediate backup
docker exec seen-postgres pg_dump -U seen seen | gzip > backups/manual_backup_$(date +%Y%m%d_%H%M%S).sql.gz
```

### Restore from Backup

```bash
# List available backups
ls -lh backups/

# Restore (WARNING: This will overwrite current database!)
docker exec -i seen-backup /restore.sh /backups/seen_backup_20260406_120000.sql.gz
```

## Monitoring

### Health Checks

```bash
# Backend health
curl http://localhost:8081/api/v1/health/live
curl http://localhost:8081/api/v1/health/ready

# Frontend health
curl http://localhost:8080/health

# Database health
docker exec seen-postgres pg_isready -U seen

# Cache health
docker exec seen-dragonfly redis-cli ping
```

### View Logs

```bash
# All services
docker compose logs -f

# Specific service
docker compose logs -f seen-backend
docker compose logs -f seen-frontend
docker compose logs -f postgres
docker compose logs -f dragonfly

# Last 100 lines
docker compose logs --tail=100 seen-backend
```

### Resource Usage

```bash
# Container stats
docker stats

# Disk usage
docker system df

# Volume usage
docker volume ls
du -sh /var/lib/docker/volumes/seen_postgres_data
```

## Maintenance

### Update Application

```bash
# Pull latest changes
git pull

# Rebuild and restart
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d --build

# Remove old images
docker image prune -f
```

### Database Maintenance

```bash
# Vacuum database
docker exec seen-postgres psql -U seen -d seen -c "VACUUM ANALYZE;"

# Check database size
docker exec seen-postgres psql -U seen -d seen -c "SELECT pg_size_pretty(pg_database_size('seen'));"

# Check table sizes
docker exec seen-postgres psql -U seen -d seen -c "SELECT schemaname, tablename, pg_size_pretty(pg_total_relation_size(schemaname||'.'||tablename)) AS size FROM pg_tables WHERE schemaname = 'public' ORDER BY pg_total_relation_size(schemaname||'.'||tablename) DESC;"
```

### Cache Maintenance

```bash
# Check cache memory usage
docker exec seen-dragonfly redis-cli INFO memory

# Check cache stats
docker exec seen-dragonfly redis-cli INFO stats

# Clear cache (if needed)
docker exec seen-dragonfly redis-cli FLUSHDB

# Check cache keys
docker exec seen-dragonfly redis-cli KEYS "seen:*"
```

## Troubleshooting

### Backend won't start

```bash
# Check logs
docker compose logs seen-backend

# Common issues:
# 1. Database not ready - wait for postgres health check
# 2. Invalid JWT secret - check .env.production.local
# 3. Missing API keys - add TMDB/IGDB credentials
```

### Frontend shows errors

```bash
# Check logs
docker compose logs seen-frontend

# Check nginx config
docker exec seen-frontend nginx -t

# Rebuild frontend
docker compose up -d --build seen-frontend
```

### Database connection issues

```bash
# Check postgres is running
docker compose ps postgres

# Check postgres logs
docker compose logs postgres

# Test connection
docker exec seen-postgres psql -U seen -d seen -c "SELECT 1;"
```

### Cache connection issues

```bash
# Check dragonfly is running
docker compose ps dragonfly

# Test connection
docker exec seen-dragonfly redis-cli ping

# Check dragonfly logs
docker compose logs dragonfly
```

## Security Checklist

- [ ] Strong JWT secret generated and configured
- [ ] Strong database password set
- [ ] HTTPS/TLS enabled with valid certificate
- [ ] Security headers configured in nginx
- [ ] CORS properly configured for your domain
- [ ] Database not exposed to public internet
- [ ] Cache not exposed to public internet
- [ ] Firewall configured (only ports 80, 443 open)
- [ ] Regular backups enabled and tested
- [ ] Log rotation configured
- [ ] Resource limits set on containers
- [ ] Environment files not committed to git
- [ ] API rate limiting enabled
- [ ] Regular security updates applied

## Performance Tuning

### Database Optimization

Already configured in `docker-compose.yml`:
- Connection pooling (25 max connections)
- Shared buffers: 256MB
- Effective cache size: 1GB
- Work memory: 2.6MB per operation

### Cache Optimization

Already configured:
- Max memory: 512MB
- Eviction policy: allkeys-lru
- Persistence enabled

### Application Optimization

- Frontend assets cached for 1 year
- Gzip compression enabled
- Connection pooling in backend
- Health check intervals optimized

## Scaling

### Horizontal Scaling

To scale the backend:

```bash
# Scale to 3 backend instances
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d --scale seen-backend=3

# Add load balancer (nginx, traefik, or haproxy)
```

### Vertical Scaling

Update resource limits in `docker-compose.prod.yml`:

```yaml
deploy:
  resources:
    limits:
      cpus: '4.0'
      memory: 4G
```

## Support

For issues and questions:
- Check logs: `docker compose logs`
- Review health checks
- Consult troubleshooting section
- Check GitHub issues

## License

See LICENSE file for details.
