67701d10ad
- Nginx now listens on HTTP only (port 80) - Remove SSL cert volume mounts from docker-compose - Remove SSL troubleshooting sections - Update docs to indicate SSL handled by Caddy/reverse proxy - Simplify nginx.conf to remove HTTPS server block
216 lines
8.7 KiB
Markdown
216 lines
8.7 KiB
Markdown
# CoopCredits Infrastructure Documentation
|
|
|
|
## Network Architecture
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────────────────┐
|
|
│ External Access │
|
|
│ coop.hobokenchicken.com │
|
|
└─────────────────────────────────┬───────────────────────────────────────┘
|
|
│ HTTPS (443)
|
|
▼
|
|
┌─────────────────────────────────────────────────────────────────────────┐
|
|
│ CoopCredits Server │
|
|
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
|
|
│ │ Nginx │ │ Frontend │ │ Backend │ │ PostgreSQL │ │
|
|
│ │ (80) │──│ (Next.js) │──│ (Express) │──│ (5432) │ │
|
|
│ └──────────────┘ └──────────────┘ └──────┬───────┘ └──────────────┘ │
|
|
│ │ │
|
|
│ ┌──────────────┐ │ ┌──────────────┐ │
|
|
│ │ Redis │◀────────┘ │ Anchor CLI │ │
|
|
│ │ (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
|
|
|
|
SSL/TLS is handled by an external reverse proxy (e.g., Caddy). The application stack runs HTTP only on port 80 internally.
|
|
|
|
## 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
|