Skip to main content

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