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.
583 lines
12 KiB
Markdown
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. |