Production Deployment
Deploy Rephole to production with Docker Compose or Kubernetes.
Docker Compose Production
docker-compose.yml
version: '3.8'
services:
# PostgreSQL
postgres:
image: postgres:15-alpine
environment:
POSTGRES_USER: rephole
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: rephole
volumes:
- postgres_data:/var/lib/postgresql/data
ports:
- "5432:5432"
healthcheck:
test: ["CMD-SHELL", "pg_isready -U rephole"]
interval: 10s
timeout: 5s
retries: 5
# Redis
redis:
image: redis:7-alpine
ports:
- "6379:6379"
volumes:
- redis_data:/data
command: redis-server --appendonly yes
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 3s
retries: 5
# ChromaDB
chromadb:
image: chromadb/chroma:latest
ports:
- "8000:8000"
volumes:
- chroma_data:/chroma/chroma
environment:
- IS_PERSISTENT=TRUE
# API Server (Producer)
api:
build:
context: .
dockerfile: Dockerfile.api
ports:
- "3000:3000"
environment:
- NODE_ENV=production
- POSTGRES_HOST=postgres
- REDIS_HOST=redis
- CHROMA_HOST=chromadb
- OPENAI_API_KEY=${OPENAI_API_KEY}
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
chromadb:
condition: service_started
restart: unless-stopped
# Background Worker (Consumer)
worker:
build:
context: .
dockerfile: Dockerfile.worker
environment:
- NODE_ENV=production
- POSTGRES_HOST=postgres
- REDIS_HOST=redis
- CHROMA_HOST=chromadb
- OPENAI_API_KEY=${OPENAI_API_KEY}
- MEMORY_MONITORING=true
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
chromadb:
condition: service_started
restart: unless-stopped
deploy:
replicas: 2
volumes:
postgres_data:
redis_data:
chroma_data:
Deploy
# Build and start
docker-compose -f docker-compose.yml up -d --build
# Scale workers
docker-compose up -d --scale worker=5
# Scale API
docker-compose up -d --scale api=3
Reverse Proxy (nginx)
Add authentication and SSL:
upstream rephole_api {
server api:3000;
}
server {
listen 443 ssl http2;
server_name api.rephole.example.com;
ssl_certificate /etc/ssl/certs/rephole.crt;
ssl_certificate_key /etc/ssl/private/rephole.key;
location / {
proxy_pass http://rephole_api;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
# Authentication
auth_basic "Rephole API";
auth_basic_user_file /etc/nginx/.htpasswd;
}
location /health {
proxy_pass http://rephole_api;
auth_basic off;
}
}
Environment Variables
Create .env for production:
NODE_ENV=production
POSTGRES_PASSWORD=<strong-random-password>
OPENAI_API_KEY=sk-...
# Optionally override defaults
VECTOR_STORE_BATCH_SIZE=2000
LOG_LEVEL=info
Health Checks
API Health
curl https://api.rephole.example.com/health
Database Health
docker exec rephole-postgres pg_isready -U rephole
Queue Health
docker exec rephole-redis redis-cli ping
Backup Strategy
PostgreSQL
# Backup
docker exec rephole-postgres pg_dump -U rephole rephole > backup.sql
# Restore
docker exec -i rephole-postgres psql -U rephole rephole < backup.sql
ChromaDB
# Backup volume
docker run --rm -v rephole_chroma_data:/data -v $(pwd):/backup \
alpine tar czf /backup/chroma-backup.tar.gz -C /data .
Redis
# Trigger backup
docker exec rephole-redis redis-cli BGSAVE
# Copy RDB file
docker cp rephole-redis:/data/dump.rdb ./redis-backup.rdb
Monitoring
Check Queue Status
docker exec rephole-redis redis-cli
# Queue statistics
KEYS bull:repo-ingestion:*
LLEN bull:repo-ingestion:waiting
LLEN bull:repo-ingestion:active
LLEN bull:repo-ingestion:completed
LLEN bull:repo-ingestion:failed
View Worker Logs
docker-compose logs -f worker
# Expected output:
# [RepoUpdateProcessor] Starting repo ingestion job xxx
# [RepoUpdateProcessor] Processing 123 files
# [RepoUpdateProcessor] ✅ Completed in 45s
Security Checklist
- Strong
POSTGRES_PASSWORD - SSL/TLS enabled
- Authentication on API endpoints
- Firewall rules for internal services
- Regular security updates
- API key rotation schedule
- Backup verification tests