# CoopCredits Infrastructure Documentation ## Network Architecture ``` ┌─────────────────────────────────────────────────────────────────────────┐ │ External Access │ │ coop.hobokenchicken.com │ └─────────────────────────────────┬───────────────────────────────────────┘ │ HTTPS (443) ▼ ┌─────────────────────────────────────────────────────────────────────────┐ │ CoopCredits Server │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │ │ Nginx │ │ Frontend │ │ Backend │ │ PostgreSQL │ │ │ │ (80/443) │──│ (Next.js) │──│ (Express) │──│ (5432) │ │ │ └──────────────┘ └──────────────┘ └──────┬───────┘ └──────────────┘ │ │ │ │ │ ┌──────────────┐ ┌──────────────┐ │ ┌──────────────┐ │ │ │ Certbot │ │ Redis │◀────────┘ │ Anchor CLI │ │ │ │ (SSL) │ │ (6379) │ │ (Optional) │ │ │ └──────────────┘ └──────────────┘ └──────────────┘ │ └──────────────────────────────────┬──────────────────────────────────────┘ │ │ Local Network (172.20.1.0/24) ┌──────────────────────────┼──────────────────────────┐ │ │ │ ▼ ▼ ▼ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ Plex │ │ Tautulli │ │ Overseer │ │172.20.1.220 │ │172.20.1.255 │ │172.20.1.225 │ │ :32400 │ │ :8181 │ │ :5055 │ └──────────────┘ └──────────────┘ └──────────────┘ ``` ## Service Details ### Plex Server (172.20.1.220:32400) - **Purpose**: Content streaming and user authentication - **Integration**: OAuth authentication for website login - **Access**: HTTP on local network, may have remote access enabled ### Tautulli (172.20.1.255:8181) - **Purpose**: Plex analytics and watch event tracking - **Integration**: Webhook notifications to CoopCredits backend - **Access**: HTTP on local network - **API Key**: Required for backend queries ### Overseer (172.20.1.225:5055) - **Purpose**: Content request management - **Integration**: API for requesting content, webhooks for status updates - **Access**: HTTP on local network - **API Key**: Required for backend integration ### CoopCredits Server - **Public Access**: coop.hobokenchicken.com (HTTPS) - **Internal Services**: Only accessible via Nginx reverse proxy - **Database**: PostgreSQL on localhost only - **Cache**: Redis on localhost only ## Communication Flow ### 1. User Authentication ``` User → Nginx → Frontend → Backend → Plex OAuth (172.20.1.220:32400) ↓ User authenticated, JWT issued ``` ### 2. Watch Event Processing ``` Plex → Tautulli → Webhook → Nginx → Backend → Solana Devnet ↓ Database updated ↓ WebSocket → User notified ``` ### 3. Content Request ``` User → Nginx → Frontend → Backend → Overseer API (172.20.1.225:5055) ↓ Request created, $COOP reserved ↓ Webhook on approval → Burn $COOP ``` ## Security Considerations ### Network Security 1. **Local Network**: All services communicate over HTTP (trusted network) 2. **External Access**: Only Nginx exposed (ports 80/443) 3. **Internal Services**: Not accessible from external network ### API Security 1. **Tautulli Webhook**: Secret verification recommended 2. **Overseer API**: API key authentication 3. **Plex OAuth**: Standard OAuth 2.0 flow 4. **JWT**: Secure tokens for session management ### Data Security 1. **Wallet Keys**: Encrypted with AES-256-GCM in database 2. **Database**: Not exposed externally 3. **Redis**: Password protected, localhost only ## Firewall Configuration ```bash # Web traffic sudo ufw allow 80/tcp sudo ufw allow 443/tcp # Internal service access (from Docker containers) sudo ufw allow from 172.20.0.0/16 to 172.20.1.0/24 # Block external access to internal services sudo ufw deny 3000/tcp # Frontend sudo ufw deny 3001/tcp # Backend sudo ufw deny 5432/tcp # PostgreSQL sudo ufw deny 6379/tcp # Redis ``` ## Docker Network Configuration ### Internal Network (coop-internal) - Containers can communicate with each other - Isolated from external network - Used for: frontend ↔ backend ↔ database ### External Network (coop-external) - Allows containers to reach local services - Subnet: 172.20.2.0/24 - Used for: backend → Tautulli/Overseer/Plex ## SSL/TLS Setup ### Let's Encrypt (Recommended) ```bash # Initial certificate docker-compose -f docker-compose.prod.yml run --rm certbot certonly \ --webroot -w /var/www/certbot \ -d coop.hobokenchicken.com \ --agree-tos --no-eff-email # Auto-renewal (configured in docker-compose) ``` ### Self-Signed (Testing only) ```bash openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ -keyout docker/nginx/ssl/key.pem \ -out docker/nginx/ssl/cert.pem \ -subj '/CN=coop.hobokenchicken.com' ``` ## Monitoring and Logging ### Log Locations - Nginx: `docker/nginx/logs/` - Backend: Docker logs (`docker-compose logs backend`) - Frontend: Docker logs (`docker-compose logs frontend`) - Database: Inside container (`/var/log/postgresql/`) ### Health Checks ```bash # Backend health curl https://coop.hobokenchicken.com/health # Database connection docker-compose exec postgres pg_isready -U coop # Service status docker-compose ps ``` ## Troubleshooting ### Cannot reach local services 1. Check Docker network: `docker network inspect coop-credits_coop-external` 2. Verify IP connectivity: `docker exec coop-backend ping 172.20.1.255` 3. Check firewall rules: `sudo ufw status` ### Webhook not received 1. Verify Tautulli can reach CoopCredits: ```bash curl -X POST https://coop.hobokenchicken.com/webhooks/tautulli \ -H "Content-Type: application/json" \ -d '{"test": true}' ``` 2. Check Nginx logs: `tail -f docker/nginx/logs/access.log` 3. Check backend logs: `docker-compose logs -f backend` ### CORS errors 1. Verify CORS_ORIGINS in .env includes your domain 2. Check backend is sending correct headers 3. Nginx should pass through CORS headers ## Performance Optimization ### Nginx Tuning - `worker_processes auto` - Use all CPU cores - `worker_connections 1024` - High connection limit - `gzip on` - Compress responses - `proxy_cache` - Cache static assets ### Database Tuning - Connection pooling via Prisma - Redis for session caching - Indexed queries on user_id, created_at ### Frontend Optimization - Next.js static generation where possible - Image optimization - Code splitting ## Backup and Recovery ### Database Backup ```bash # Automated backup script docker-compose exec -T postgres pg_dump -U coop coop_credits > backup_$(date +%Y%m%d).sql ``` ### Wallet Recovery - Private keys are encrypted in database - Backup keys stored securely (encrypted) - Recovery requires encryption key from .env ### Configuration Backup - `.env` file (contains all secrets) - `docker/nginx/ssl/` certificates - `docker-compose.prod.yml` service config