Skip to content

Latest commit

 

History

History
838 lines (693 loc) · 16.8 KB

File metadata and controls

838 lines (693 loc) · 16.8 KB

BotForge RAG - Deployment Guide

Overview

This guide covers deploying BotForge RAG in various environments, from development to production-grade deployments.

🏗️ Architecture Components

Core Services

  • BotForge API: Main FastAPI application
  • PostgreSQL: Primary database for bots, MCP servers, and logs
  • Redis: Cache for embeddings and session data
  • Vector Model: SentenceTransformers embedding model

External Dependencies

  • OpenAI API: For LLM responses
  • External MCP Servers: Custom tool servers

🐳 Docker Deployment

Docker Compose (Recommended for Development)

Create docker-compose.yml:

version: '3.8'

services:
  postgres:
    image: postgres:15
    environment:
      POSTGRES_DB: botforge
      POSTGRES_USER: botforge
      POSTGRES_PASSWORD: botforge123
    volumes:
      - postgres_data:/var/lib/postgresql/data
      - ./create.sql:/docker-entrypoint-initdb.d/create.sql
    ports:
      - "5432:5432"
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U botforge"]
      interval: 30s
      timeout: 10s
      retries: 3

  redis:
    image: redis:7-alpine
    ports:
      - "6379:6379"
    volumes:
      - redis_data:/data
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 30s
      timeout: 10s
      retries: 3

  botforge-api:
    build: .
    ports:
      - "8000:8000"
    environment:
      - DATABASE_URL=postgresql+asyncpg://botforge:botforge123@postgres:5432/botforge
      - REDIS_URL=redis://redis:6379
      - OPENAI_API_KEY=${OPENAI_API_KEY}
      - VECTOR_MODEL_PATH=all-MiniLM-L6-v2
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_healthy
    volumes:
      - ./models:/app/models
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
      interval: 30s
      timeout: 10s
      retries: 3

volumes:
  postgres_data:
  redis_data:

Dockerfile

Create Dockerfile:

FROM python:3.9-slim

# Set working directory
WORKDIR /app

# Install system dependencies
RUN apt-get update && apt-get install -y \
    curl \
    build-essential \
    && rm -rf /var/lib/apt/lists/*

# Copy requirements and install Python dependencies
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# Copy application code
COPY src/ ./src/
COPY config/ ./config/

# Create models directory for vector model cache
RUN mkdir -p models

# Set Python path
ENV PYTHONPATH=/app/src

# Expose port
EXPOSE 8000

# Health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
  CMD curl -f http://localhost:8000/health || exit 1

# Run the application
CMD ["python", "-m", "botforge.main"]

Environment Configuration

Create .env file:

# Database
DATABASE_URL=postgresql+asyncpg://botforge:botforge123@localhost:5432/botforge

# Redis
REDIS_URL=redis://localhost:6379

# OpenAI
OPENAI_API_KEY=sk-your-openai-api-key-here

# Vector Model
VECTOR_MODEL_PATH=all-MiniLM-L6-v2

# Server Configuration
HOST=0.0.0.0
PORT=8000
DEBUG=false
LOG_LEVEL=INFO

# Performance Tuning
MAX_CHUNKS=5
SIMILARITY_THRESHOLD=0.7
MCP_TIMEOUT_SECONDS=30
MCP_RETRY_ATTEMPTS=3

# Security
ALLOWED_ORIGINS=http://localhost:3000,https://yourdomain.com
RATE_LIMIT_PER_MINUTE=100

Deployment Commands

# Build and start services
docker-compose up -d

# Check logs
docker-compose logs -f botforge-api

# Run database migrations
docker-compose exec botforge-api python -m alembic upgrade head

# Scale API instances
docker-compose up -d --scale botforge-api=3

# Stop services
docker-compose down

☸️ Kubernetes Deployment

Namespace Configuration

k8s/namespace.yaml:

apiVersion: v1
kind: Namespace
metadata:
  name: botforge
  labels:
    name: botforge

ConfigMap

k8s/configmap.yaml:

apiVersion: v1
kind: ConfigMap
metadata:
  name: botforge-config
  namespace: botforge
data:
  HOST: "0.0.0.0"
  PORT: "8000"
  LOG_LEVEL: "INFO"
  VECTOR_MODEL_PATH: "all-MiniLM-L6-v2"
  MAX_CHUNKS: "5"
  SIMILARITY_THRESHOLD: "0.7"
  MCP_TIMEOUT_SECONDS: "30"
  MCP_RETRY_ATTEMPTS: "3"

Secrets

k8s/secrets.yaml:

apiVersion: v1
kind: Secret
metadata:
  name: botforge-secrets
  namespace: botforge
type: Opaque
data:
  DATABASE_URL: <base64-encoded-database-url>
  REDIS_URL: <base64-encoded-redis-url>
  OPENAI_API_KEY: <base64-encoded-openai-key>

PostgreSQL Deployment

k8s/postgres.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: postgres
  namespace: botforge
spec:
  replicas: 1
  selector:
    matchLabels:
      app: postgres
  template:
    metadata:
      labels:
        app: postgres
    spec:
      containers:
      - name: postgres
        image: postgres:15
        env:
        - name: POSTGRES_DB
          value: botforge
        - name: POSTGRES_USER
          value: botforge
        - name: POSTGRES_PASSWORD
          valueFrom:
            secretKeyRef:
              name: postgres-secret
              key: password
        ports:
        - containerPort: 5432
        volumeMounts:
        - name: postgres-storage
          mountPath: /var/lib/postgresql/data
        - name: init-sql
          mountPath: /docker-entrypoint-initdb.d
      volumes:
      - name: postgres-storage
        persistentVolumeClaim:
          claimName: postgres-pvc
      - name: init-sql
        configMap:
          name: postgres-init

---
apiVersion: v1
kind: Service
metadata:
  name: postgres-service
  namespace: botforge
spec:
  selector:
    app: postgres
  ports:
  - port: 5432
    targetPort: 5432

Redis Deployment

k8s/redis.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis
  namespace: botforge
spec:
  replicas: 1
  selector:
    matchLabels:
      app: redis
  template:
    metadata:
      labels:
        app: redis
    spec:
      containers:
      - name: redis
        image: redis:7-alpine
        ports:
        - containerPort: 6379
        volumeMounts:
        - name: redis-storage
          mountPath: /data
      volumes:
      - name: redis-storage
        persistentVolumeClaim:
          claimName: redis-pvc

---
apiVersion: v1
kind: Service
metadata:
  name: redis-service
  namespace: botforge
spec:
  selector:
    app: redis
  ports:
  - port: 6379
    targetPort: 6379

BotForge API Deployment

k8s/botforge-api.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: botforge-api
  namespace: botforge
spec:
  replicas: 3
  selector:
    matchLabels:
      app: botforge-api
  template:
    metadata:
      labels:
        app: botforge-api
    spec:
      containers:
      - name: botforge-api
        image: botforge/botforge-rag:latest
        ports:
        - containerPort: 8000
        env:
        - name: DATABASE_URL
          valueFrom:
            secretKeyRef:
              name: botforge-secrets
              key: DATABASE_URL
        - name: REDIS_URL
          valueFrom:
            secretKeyRef:
              name: botforge-secrets
              key: REDIS_URL
        - name: OPENAI_API_KEY
          valueFrom:
            secretKeyRef:
              name: botforge-secrets
              key: OPENAI_API_KEY
        envFrom:
        - configMapRef:
            name: botforge-config
        resources:
          requests:
            memory: "512Mi"
            cpu: "250m"
          limits:
            memory: "1Gi"
            cpu: "500m"
        livenessProbe:
          httpGet:
            path: /health
            port: 8000
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /health
            port: 8000
          initialDelaySeconds: 5
          periodSeconds: 5

---
apiVersion: v1
kind: Service
metadata:
  name: botforge-api-service
  namespace: botforge
spec:
  selector:
    app: botforge-api
  ports:
  - port: 80
    targetPort: 8000
  type: ClusterIP

Ingress Configuration

k8s/ingress.yaml:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: botforge-ingress
  namespace: botforge
  annotations:
    kubernetes.io/ingress.class: nginx
    cert-manager.io/cluster-issuer: letsencrypt-prod
    nginx.ingress.kubernetes.io/rate-limit: "100"
    nginx.ingress.kubernetes.io/rate-limit-window: "1m"
spec:
  tls:
  - hosts:
    - api.botforge.com
    secretName: botforge-tls
  rules:
  - host: api.botforge.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: botforge-api-service
            port:
              number: 80

Deployment Commands

# Create namespace
kubectl apply -f k8s/namespace.yaml

# Apply configurations
kubectl apply -f k8s/configmap.yaml
kubectl apply -f k8s/secrets.yaml

# Deploy services
kubectl apply -f k8s/postgres.yaml
kubectl apply -f k8s/redis.yaml
kubectl apply -f k8s/botforge-api.yaml
kubectl apply -f k8s/ingress.yaml

# Check status
kubectl get pods -n botforge
kubectl get services -n botforge

# View logs
kubectl logs -f deployment/botforge-api -n botforge

# Scale deployment
kubectl scale deployment botforge-api --replicas=5 -n botforge

🚀 Production Deployment

Infrastructure Requirements

Minimum Requirements

  • CPU: 2 vCPU
  • Memory: 4 GB RAM
  • Storage: 20 GB SSD
  • Network: 1 Gbps

Recommended Production

  • CPU: 4+ vCPU
  • Memory: 8+ GB RAM
  • Storage: 100+ GB SSD
  • Network: 10 Gbps
  • Load Balancer: Yes
  • Auto-scaling: Yes

Database Configuration

PostgreSQL Production Settings

postgresql.conf:

# Connection Settings
max_connections = 200
shared_buffers = 256MB
effective_cache_size = 1GB
maintenance_work_mem = 64MB

# Write-Ahead Logging
wal_buffers = 16MB
checkpoint_completion_target = 0.9
wal_writer_delay = 200ms

# Query Tuning
random_page_cost = 1.1
effective_io_concurrency = 200

# Logging
log_destination = 'stderr'
logging_collector = on
log_directory = 'log'
log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log'
log_min_duration_statement = 1000

Redis Production Settings

redis.conf:

# Memory Management
maxmemory 2gb
maxmemory-policy allkeys-lru

# Persistence
save 900 1
save 300 10
save 60 10000

# Security
requirepass your-redis-password
rename-command FLUSHDB ""
rename-command FLUSHALL ""

# Performance
tcp-keepalive 300
timeout 0

Load Balancer Configuration

Nginx Configuration

nginx.conf:

upstream botforge_api {
    least_conn;
    server 10.0.1.10:8000 max_fails=3 fail_timeout=30s;
    server 10.0.1.11:8000 max_fails=3 fail_timeout=30s;
    server 10.0.1.12:8000 max_fails=3 fail_timeout=30s;
}

server {
    listen 80;
    server_name api.botforge.com;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name api.botforge.com;

    ssl_certificate /etc/ssl/certs/botforge.crt;
    ssl_certificate_key /etc/ssl/private/botforge.key;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384;

    # Rate limiting
    limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
    limit_req zone=api burst=20 nodelay;

    # Compression
    gzip on;
    gzip_types application/json text/plain application/javascript;

    location / {
        proxy_pass http://botforge_api;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        
        # Timeouts
        proxy_connect_timeout 60s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;
        
        # Health checks
        proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
    }

    location /health {
        proxy_pass http://botforge_api;
        access_log off;
    }
}

Monitoring & Observability

Prometheus Configuration

prometheus.yml:

global:
  scrape_interval: 15s

scrape_configs:
  - job_name: 'botforge-api'
    static_configs:
      - targets: ['localhost:8000']
    metrics_path: /metrics
    scrape_interval: 15s

  - job_name: 'postgres'
    static_configs:
      - targets: ['localhost:9187']

  - job_name: 'redis'
    static_configs:
      - targets: ['localhost:9121']

Grafana Dashboard

Key metrics to monitor:

  • Query Response Times: P50, P95, P99
  • Intent Detection Accuracy: Success rate
  • MCP Tool Execution: Success rate, latency
  • Database Performance: Connection pool, query time
  • Cache Hit Rates: Redis performance
  • Error Rates: 4xx, 5xx responses

Security Configuration

Environment Security

# Use strong passwords
export POSTGRES_PASSWORD=$(openssl rand -base64 32)
export REDIS_PASSWORD=$(openssl rand -base64 32)

# Restrict database access
export DATABASE_URL="postgresql+asyncpg://botforge:${POSTGRES_PASSWORD}@db-host:5432/botforge?sslmode=require"

# Use secure Redis
export REDIS_URL="redis://:${REDIS_PASSWORD}@redis-host:6379/0"

# Secure OpenAI key
export OPENAI_API_KEY="sk-your-secure-key"

Network Security

# Firewall rules (example for iptables)
iptables -A INPUT -p tcp --dport 8000 -s 10.0.0.0/8 -j ACCEPT
iptables -A INPUT -p tcp --dport 5432 -s 10.0.1.0/24 -j ACCEPT
iptables -A INPUT -p tcp --dport 6379 -s 10.0.1.0/24 -j ACCEPT
iptables -A INPUT -j DROP

Backup & Recovery

Database Backup

#!/bin/bash
# backup-db.sh

BACKUP_DIR="/backups/postgres"
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="botforge_backup_${DATE}.sql"

# Create backup
pg_dump -h localhost -U botforge -d botforge > "${BACKUP_DIR}/${BACKUP_FILE}"

# Compress backup
gzip "${BACKUP_DIR}/${BACKUP_FILE}"

# Upload to S3 (optional)
aws s3 cp "${BACKUP_DIR}/${BACKUP_FILE}.gz" s3://botforge-backups/

# Clean old backups (keep last 7 days)
find ${BACKUP_DIR} -name "*.gz" -mtime +7 -delete

Redis Backup

#!/bin/bash
# backup-redis.sh

BACKUP_DIR="/backups/redis"
DATE=$(date +%Y%m%d_%H%M%S)

# Create Redis backup
redis-cli --rdb "${BACKUP_DIR}/dump_${DATE}.rdb"

# Upload to S3
aws s3 cp "${BACKUP_DIR}/dump_${DATE}.rdb" s3://botforge-backups/redis/

Auto-scaling Configuration

Kubernetes HPA

k8s/hpa.yaml:

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: botforge-api-hpa
  namespace: botforge
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: botforge-api
  minReplicas: 3
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70
  - type: Resource
    resource:
      name: memory
      target:
        type: Utilization
        averageUtilization: 80

Performance Optimization

Application Tuning

# src/botforge/core/config.py
class ProductionSettings(Settings):
    # Connection pooling
    database_pool_size: int = 20
    database_max_overflow: int = 30
    
    # Redis connection pool
    redis_pool_size: int = 50
    redis_pool_timeout: int = 30
    
    # Performance tuning
    max_concurrent_requests: int = 100
    request_timeout: int = 30
    
    # Caching
    cache_ttl: int = 3600
    embedding_cache_size: int = 10000

Vector Model Optimization

# Pre-load and warm up models
async def startup_event():
    # Warm up vector model
    vector_model = SentenceTransformer('all-MiniLM-L6-v2')
    vector_model.encode("warmup text")
    
    # Pre-compile common queries
    await redis_client.set("model:ready", "true")

Deployment Checklist

Pre-deployment

  • Environment variables configured
  • Database migrations applied
  • SSL certificates installed
  • Monitoring configured
  • Backup procedures tested
  • Load testing completed

Post-deployment

  • Health checks passing
  • Metrics collection working
  • Error tracking enabled
  • Log aggregation configured
  • Alert rules configured
  • Documentation updated

Troubleshooting

Common Issues

High Memory Usage:

# Check vector model memory
ps aux | grep python
# Optimize model loading
export SENTENCE_TRANSFORMERS_HOME=/tmp/models

Database Connection Issues:

# Check connection pool
SELECT count(*) FROM pg_stat_activity;
# Increase pool size
export DATABASE_POOL_SIZE=30

Redis Connection Issues:

# Check Redis connections
redis-cli info clients
# Increase connection pool
export REDIS_POOL_SIZE=100

Monitoring Commands

# Check API health
curl -f https://api.botforge.com/health

# Monitor database performance
kubectl exec -it postgres-pod -- psql -U botforge -c "SELECT * FROM pg_stat_activity;"

# Check API logs
kubectl logs -f deployment/botforge-api -n botforge

# Monitor resource usage
kubectl top pods -n botforge

This deployment guide provides comprehensive instructions for deploying BotForge RAG in production environments with proper security, monitoring, and scalability considerations.