mirror of
https://github.com/Dvorinka/SEEN.git
synced 2026-06-03 20:13:02 +00:00
small fix, don't worry about it
This commit is contained in:
@@ -0,0 +1,432 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user