rentcache/docs/DEPLOYMENT.md
Ryan Malloy 345ad00692 Add comprehensive production documentation
Documentation created:
- Updated README.md with Docker deployment and production domain
- docs/DEPLOYMENT.md: Complete Docker/Caddy deployment guide
- docs/ARCHITECTURE.md: System design and caching strategies
- docs/QUICKSTART.md: 5-minute setup with real examples
- Updated USAGE.md with production URLs

Key updates:
- Production domain: https://rentcache.l.supported.systems
- Docker Compose with Caddy reverse proxy
- Make commands for easy management
- Cost savings examples (70-90% reduction)
- Complete architecture documentation
- Production deployment checklist
- Monitoring and maintenance guides

The system is now fully documented for production deployment.
2025-09-10 14:22:36 -06:00

583 lines
12 KiB
Markdown

# Deployment Guide
This guide covers deploying RentCache in production using Docker, with Caddy reverse proxy, and comprehensive monitoring.
## 🐳 Docker Deployment
### Prerequisites
- **Docker Engine**: 20.10+ with Compose V2
- **External Caddy Network**: For reverse proxy integration
- **Domain**: Configured with DNS pointing to your server
- **SSL Certificate**: Automatic with Caddy (Let's Encrypt)
### Quick Production Deployment
```bash
# Clone repository
git clone https://git.supported.systems/MCP/rentcache.git
cd rentcache
# Set up environment
cp .env.example .env
nano .env # Configure your settings
# Deploy with reverse proxy
make setup
```
This command:
1. Creates the external Caddy network if needed
2. Builds the Docker images
3. Starts services with reverse proxy
4. Makes RentCache available at your domain
### Environment Configuration
#### Production .env File
```env
# Domain Configuration
DOMAIN=your-domain.com
COMPOSE_PROJECT=rentcache-prod
# Mode Configuration
MODE=production
DEBUG=false
LOG_LEVEL=INFO
# Server Configuration
HOST=0.0.0.0
PORT=8000
# Database Configuration (Production)
DATABASE_URL=postgresql://rentcache:secure_password@postgres:5432/rentcache
DATABASE_ECHO=false
# Redis Configuration (Recommended for Production)
REDIS_URL=redis://redis:6379
REDIS_ENABLED=true
# Cache Settings (Optimized for Production)
DEFAULT_CACHE_TTL=7200
EXPENSIVE_ENDPOINTS_TTL=172800
ENABLE_STALE_WHILE_REVALIDATE=true
# Rate Limiting (Production Limits)
ENABLE_RATE_LIMITING=true
GLOBAL_RATE_LIMIT=2000/hour
PER_ENDPOINT_RATE_LIMIT=100/minute
# Security (Restrict Access)
ALLOWED_HOSTS=your-domain.com,api.your-domain.com
CORS_ORIGINS=https://your-domain.com,https://app.your-domain.com
# Monitoring
ENABLE_METRICS=true
LOG_FORMAT=json
```
### Docker Compose Production Setup
The included `docker-compose.yml` supports multiple deployment scenarios:
#### Basic Production Deployment
```bash
# Production mode with PostgreSQL
MODE=production docker compose up -d rentcache postgres
```
#### High-Performance Deployment with Redis
```bash
# Production with Redis caching
MODE=production docker compose --profile redis up -d
```
#### Development with Hot Reload
```bash
# Development mode with file watching
make dev
```
## 🌐 Reverse Proxy with Caddy
### Caddy Docker Proxy Integration
RentCache is designed to work with [caddy-docker-proxy](https://github.com/lucaslorentz/caddy-docker-proxy) for automatic HTTPS and load balancing.
#### Setup External Caddy Network
```bash
# Create the external network (if not exists)
docker network create caddy
# Verify network exists
docker network ls | grep caddy
```
#### Caddy Labels Configuration
The `docker-compose.yml` includes automatic Caddy configuration:
```yaml
services:
rentcache:
# ... other config
networks:
- caddy
labels:
caddy: ${DOMAIN:-rentcache.l.supported.systems}
caddy.reverse_proxy: "{{upstreams}}"
caddy.header.X-Forwarded-Proto: https
caddy.header.X-Real-IP: "{remote_host}"
```
#### Manual Caddy Configuration
If using standalone Caddy, create a `Caddyfile`:
```caddyfile
your-domain.com {
reverse_proxy rentcache:8000
# Security headers
header {
X-Content-Type-Options nosniff
X-Frame-Options DENY
X-XSS-Protection "1; mode=block"
Strict-Transport-Security "max-age=31536000;"
}
# Health check endpoint
handle /health {
reverse_proxy rentcache:8000
}
# API endpoints
handle /api/* {
reverse_proxy rentcache:8000
}
# Admin endpoints (restrict access)
handle /admin/* {
reverse_proxy rentcache:8000
# Add basic auth or IP restrictions here
}
}
```
## 🗄️ Database Configuration
### PostgreSQL Production Setup
#### Using Docker Compose
```yaml
services:
postgres:
image: postgres:15-alpine
environment:
POSTGRES_DB: rentcache
POSTGRES_USER: rentcache
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_INITDB_ARGS: "--auth-host=scram-sha-256"
volumes:
- postgres_data:/var/lib/postgresql/data
- ./postgres/init.sql:/docker-entrypoint-initdb.d/init.sql
networks:
- caddy
restart: unless-stopped
command: >
postgres
-c shared_preload_libraries=pg_stat_statements
-c max_connections=200
-c shared_buffers=256MB
-c effective_cache_size=1GB
-c maintenance_work_mem=64MB
-c checkpoint_completion_target=0.9
-c wal_buffers=16MB
-c default_statistics_target=100
volumes:
postgres_data:
driver: local
```
#### External PostgreSQL
For external PostgreSQL (AWS RDS, Google Cloud SQL, etc.):
```env
DATABASE_URL=postgresql://username:password@host:5432/database?sslmode=require
DATABASE_ECHO=false
```
### Redis Configuration
#### Docker Redis
```yaml
services:
redis:
image: redis:7-alpine
command: >
redis-server
--appendonly yes
--appendfsync everysec
--save 900 1
--save 300 10
--save 60 10000
--maxmemory 512mb
--maxmemory-policy allkeys-lru
volumes:
- redis_data:/data
networks:
- caddy
restart: unless-stopped
profiles:
- redis
volumes:
redis_data:
driver: local
```
#### External Redis
```env
REDIS_URL=redis://username:password@host:6379/0
REDIS_ENABLED=true
```
## 🔐 Security Configuration
### SSL/TLS
With Caddy, SSL is automatic using Let's Encrypt. For manual SSL:
```caddyfile
your-domain.com {
tls your-email@domain.com # Let's Encrypt
# OR
tls /path/to/cert.pem /path/to/key.pem # Custom certificates
reverse_proxy rentcache:8000
}
```
### API Key Security
```bash
# Create production API key with strict limits
docker compose exec rentcache uv run rentcache create-key production_app YOUR_RENTCAST_KEY \
--daily-limit 5000 \
--monthly-limit 100000 \
--expires 2024-12-31
# Create development key with higher limits
docker compose exec rentcache uv run rentcache create-key dev_app YOUR_RENTCAST_KEY \
--daily-limit 10000 \
--monthly-limit 200000
```
### Network Security
```yaml
# Restrict network access
services:
rentcache:
networks:
- caddy
- internal
# Don't expose ports directly in production
postgres:
networks:
- internal # Only internal network
# No external access
redis:
networks:
- internal # Only internal network
networks:
caddy:
external: true
internal:
driver: bridge
```
## 📊 Monitoring and Logging
### Health Checks
```yaml
services:
rentcache:
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
```
### Logging Configuration
#### JSON Structured Logging
```env
LOG_FORMAT=json
LOG_LEVEL=INFO
```
#### Log Aggregation with Docker
```yaml
services:
rentcache:
logging:
driver: "json-file"
options:
max-size: "100m"
max-file: "5"
tag: "rentcache-{{.Name}}"
```
#### Centralized Logging
For production, consider using:
- **ELK Stack** (Elasticsearch, Logstash, Kibana)
- **Grafana Loki** with Promtail
- **Fluentd** or **Fluent Bit**
Example Promtail configuration:
```yaml
# promtail-config.yml
server:
http_listen_port: 9080
grpc_listen_port: 0
positions:
filename: /tmp/positions.yaml
clients:
- url: http://loki:3100/loki/api/v1/push
scrape_configs:
- job_name: rentcache
docker_sd_configs:
- host: unix:///var/run/docker.sock
refresh_interval: 5s
relabel_configs:
- source_labels: ['__meta_docker_container_label_com_docker_compose_service']
target_label: 'service'
- source_labels: ['__meta_docker_container_name']
target_label: 'container'
```
### Metrics Collection
#### Prometheus Integration
```yaml
# prometheus.yml
scrape_configs:
- job_name: 'rentcache'
static_configs:
- targets: ['rentcache:8000']
metrics_path: '/metrics'
scrape_interval: 30s
scrape_timeout: 10s
```
#### Grafana Dashboard
Key metrics to monitor:
- **Cache Hit Ratio**: Target > 80%
- **Response Time**: 95th percentile < 200ms
- **Error Rate**: < 1%
- **API Cost**: Daily/monthly spending
- **Request Volume**: Requests per minute
- **Database Performance**: Query time, connection pool
## 🚀 Production Deployment Checklist
### Pre-Deployment
- [ ] **Environment Variables**: Configure production .env
- [ ] **SSL Certificates**: Verify domain and SSL setup
- [ ] **Database**: PostgreSQL configured and accessible
- [ ] **Redis**: Optional but recommended for performance
- [ ] **Monitoring**: Health checks and metrics collection
- [ ] **Backup Strategy**: Database and configuration backups
- [ ] **Security**: Network restrictions and API key management
### Deployment Steps
```bash
# 1. Clone and configure
git clone https://git.supported.systems/MCP/rentcache.git
cd rentcache
cp .env.example .env
# Edit .env with production settings
# 2. Deploy
make setup
# 3. Verify deployment
curl https://your-domain.com/health
# 4. Create API keys
make create-key NAME=production_app KEY=your_rentcast_key
# 5. Test API access
curl -H "Authorization: Bearer your_rentcast_key" \
"https://your-domain.com/api/v1/properties?city=Austin&state=TX&limit=1"
# 6. Monitor metrics
curl https://your-domain.com/metrics
```
### Post-Deployment
- [ ] **Monitor Logs**: Check for errors and warnings
- [ ] **Test All Endpoints**: Verify API functionality
- [ ] **Cache Performance**: Monitor hit ratios
- [ ] **Cost Tracking**: Track API cost savings
- [ ] **Backup Verification**: Test restore procedures
- [ ] **Performance Baseline**: Establish performance metrics
## 🔄 Maintenance and Updates
### Regular Maintenance
```bash
# Update containers
docker compose pull
docker compose up -d
# Clean old images
docker system prune -f
# Check logs
make logs
# Monitor health
make health
# View statistics
make stats
```
### Database Maintenance
```bash
# PostgreSQL maintenance
docker compose exec postgres psql -U rentcache -d rentcache -c "VACUUM ANALYZE;"
# Clear old cache entries (older than 7 days)
docker compose exec rentcache uv run rentcache clear-cache --older-than 168
```
### Backup Procedures
```bash
# Database backup
docker compose exec postgres pg_dump -U rentcache rentcache > backup-$(date +%Y%m%d).sql
# Configuration backup
tar -czf config-backup-$(date +%Y%m%d).tar.gz .env docker-compose.yml
# Restore database
docker compose exec -T postgres psql -U rentcache -d rentcache < backup-20240115.sql
```
## 🚨 Troubleshooting
### Common Issues
#### Service Won't Start
```bash
# Check logs
docker compose logs rentcache
# Check network
docker network ls | grep caddy
# Verify configuration
docker compose config
```
#### SSL Certificate Issues
```bash
# Check Caddy logs
docker logs caddy-docker-proxy
# Force certificate renewal
docker exec caddy-docker-proxy caddy reload
```
#### Database Connection Issues
```bash
# Test database connection
docker compose exec rentcache uv run python -c "
from sqlalchemy import create_engine
engine = create_engine('$DATABASE_URL')
print('Database connection successful!')
"
```
#### High Response Times
```bash
# Enable Redis if not already
docker compose --profile redis up -d
# Check cache hit ratio
curl https://your-domain.com/metrics | jq '.cache_hit_ratio'
# Monitor database performance
docker compose exec postgres psql -U rentcache -d rentcache -c "
SELECT query, mean_time, calls
FROM pg_stat_statements
ORDER BY mean_time DESC
LIMIT 10;"
```
### Performance Tuning
#### Database Optimization
```sql
-- Create indexes for better performance
CREATE INDEX IF NOT EXISTS idx_cache_entries_endpoint ON cache_entries(endpoint);
CREATE INDEX IF NOT EXISTS idx_cache_entries_created_at ON cache_entries(created_at);
CREATE INDEX IF NOT EXISTS idx_usage_stats_api_key_id ON usage_stats(api_key_id);
CREATE INDEX IF NOT EXISTS idx_usage_stats_created_at ON usage_stats(created_at);
```
#### Application Tuning
```env
# Increase cache TTLs for stable data
DEFAULT_CACHE_TTL=7200
EXPENSIVE_ENDPOINTS_TTL=172800
# Optimize rate limits
GLOBAL_RATE_LIMIT=5000/hour
PER_ENDPOINT_RATE_LIMIT=200/minute
```
---
Ready for production? Ensure you've followed all security best practices and monitoring is properly configured. Check the [Architecture Guide](ARCHITECTURE.md) for system design details.