Skip to main content

Deployment Guide

Complete deployment guide for the Enclava platform, covering development setup, production deployment, configuration management, and operational best practices.

Quick Start

Prerequisites

  • Docker & Docker Compose: Latest versions recommended
  • Git: For cloning the repository
  • Minimum System Requirements: 4GB RAM, 2 CPU cores, 10GB storage

Development Deployment

Get Enclava running locally in under 5 minutes:

# Clone the repository
git clone https://github.com/enclava-ai/enclava.git
cd enclava

# Copy environment variables
cp .env.example .env
# edit the .env file with your preferred settings
vim .env

# Start the platform
docker compose up --build

Docker Architecture

Service Overview

services:
enclava-nginx: # Reverse proxy and load balancer
enclava-migrate: # Database migration runner
enclava-backend: # FastAPI application server
enclava-frontend: # Next.js web interface
enclava-postgres: # Primary database
enclava-redis: # Cache and session store
enclava-qdrant: # Vector database for RAG
privatemode-proxy: # Confidential computing proxy

Port Configuration

ServiceInternal PortExternal PortPurpose
Nginx8080Main application access
Frontend30003002Direct frontend development
Backend8000-Internal API (via Nginx)
PostgreSQL5432-Database access
Redis6379-Cache and sessions
Qdrant633356333Vector database UI
Privatemode808058080TEE proxy service

Network Architecture

Internet → Nginx (80) → {
/api/* → Backend (8000)
/* → Frontend (3000)
}

Backend ↔ PostgreSQL (5432)
Backend ↔ Redis (6379)
Backend ↔ Qdrant (6333)
Backend ↔ Privatemode (8080)

Configuration Management

Environment Variables

Create a .env file in the project root:

# Core Platform Configuration
JWT_SECRET=your-super-secret-jwt-key-here
DATABASE_URL=postgresql://enclava_user:enclava_pass@enclava-postgres:5432/enclava_db
REDIS_URL=redis://enclava-redis:6379

# Application Settings
BASE_URL=http://localhost:80
ADMIN_USER=admin
ADMIN_PASSWORD=secure_admin_password

# LLM Service Configuration
PRIVATEMODE_API_KEY=your-privatemode-api-key

# Development & Debugging
LOG_LLM_PROMPTS=false
APP_DEBUG=false
APP_LOG_LEVEL=INFO

# Port Configuration (Internal)
BACKEND_INTERNAL_PORT=8000
FRONTEND_INTERNAL_PORT=3000

Security Configuration

JWT Secret Generation:

# Generate secure JWT secret
openssl rand -hex 32

Database Configuration

PostgreSQL Settings:

# docker-compose.yml
enclava-postgres:
image: postgres:16
environment:
POSTGRES_DB: enclava_db
POSTGRES_USER: enclava_user
POSTGRES_PASSWORD: enclava_pass
volumes:
- enclava-postgres-data:/var/lib/postgresql/data

Automated Migrations:

enclava-migrate:
build:
context: ./backend
dockerfile: Dockerfile.migrate
depends_on:
- enclava-postgres
command: ["/usr/local/bin/migrate.sh"]
restart: "no" # Run once and exit

Production Deployment

Production Docker Compose

Create docker-compose.prod.yml:

name: enclava-production

services:
enclava-nginx:
image: nginx:alpine
ports:
- "443:443"
- "80:80"
volumes:
- ./nginx/nginx.prod.conf:/etc/nginx/nginx.conf:ro
- ./ssl:/etc/nginx/ssl:ro
depends_on:
- enclava-backend
- enclava-frontend
restart: unless-stopped

enclava-backend:
build:
context: ./backend
dockerfile: Dockerfile.prod
environment:
- DATABASE_URL=${DATABASE_URL}
- REDIS_URL=${REDIS_URL}
- JWT_SECRET=${JWT_SECRET}
- PRIVATEMODE_API_KEY=${PRIVATEMODE_API_KEY}
- APP_DEBUG=false
- APP_LOG_LEVEL=WARNING
volumes:
- ./logs:/app/logs
- ./storage:/app/storage
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
interval: 30s
timeout: 10s
retries: 3

enclava-frontend:
build:
context: ./frontend
dockerfile: Dockerfile.prod
environment:
- NODE_ENV=production
- BASE_URL=${BASE_URL}
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000"]
interval: 30s
timeout: 10s
retries: 3

SSL/TLS Configuration

Nginx SSL Configuration:

# nginx.prod.conf
server {
listen 443 ssl http2;
server_name your-domain.com;

ssl_certificate /etc/nginx/ssl/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;

# API routing
location /api/ {
proxy_pass http://enclava-backend:8000;
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;
}

# Frontend routing
location / {
proxy_pass http://enclava-frontend:3000;
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;
}
}

# HTTP to HTTPS redirect
server {
listen 80;
server_name your-domain.com;
return 301 https://$server_name$request_uri;
}

Database Production Setup

External PostgreSQL:

# Environment variables for external database
DATABASE_URL=postgresql://enclava_user:secure_password@postgres.example.com:5432/enclava_production

Database Security:

  • Enable SSL connections
  • Use strong passwords
  • Configure firewall rules
  • Regular backups with encryption
  • Connection pooling limits

Backup Strategy:

#!/bin/bash
# backup.sh
DATE=$(date +%Y%m%d_%H%M%S)
pg_dump $DATABASE_URL | gzip > "enclava_backup_${DATE}.sql.gz"
aws s3 cp "enclava_backup_${DATE}.sql.gz" s3://your-backup-bucket/

Security Hardening

Production Security Checklist

Application Security

  • Strong JWT secret (32+ characters)
  • Encrypted API keys in database
  • HTTPS-only configuration
  • Secure session cookies
  • Rate limiting enabled
  • Threat detection active

Infrastructure Security

  • Firewall configured (allow only 80, 443)
  • SSH key-based authentication
  • Regular security updates
  • Log monitoring configured
  • Backup encryption enabled
  • Network segmentation

Data Protection

  • Database encryption at rest
  • Redis password authentication
  • File storage encryption
  • Audit logging enabled
  • GDPR compliance measures

Firewall Configuration

Ubuntu/Debian (UFW):

# Basic firewall setup
ufw default deny incoming
ufw default allow outgoing
ufw allow ssh
ufw allow 80/tcp
ufw allow 443/tcp
ufw enable

Docker Network Security:

# Isolated network
networks:
enclava-net:
driver: bridge
internal: false
ipam:
config:
- subnet: 172.20.0.0/16

**Log Aggregation:**
```bash
# View all service logs
docker compose logs -f

# Specific service logs
docker compose logs -f enclava-backend
docker compose logs -f enclava-frontend

# Follow new logs only
docker compose logs -f --tail=100

Metrics & Analytics

Built-in Analytics:

  • Request tracking and response times
  • API usage by key and model
  • Error rates and status codes
  • Cost tracking and budget monitoring

External Monitoring:

# Add Prometheus metrics
enclava-prometheus:
image: prom/prometheus
ports:
- "9090:9090"
volumes:
- ./monitoring/prometheus.yml:/etc/prometheus/prometheus.yml

enclava-grafana:
image: grafana/grafana
ports:
- "3001:3000"
volumes:
- grafana-data:/var/lib/grafana

Migration Failures:

# Check migration status
docker compose exec enclava-backend alembic current

# View migration history
docker compose exec enclava-backend alembic history

# Run specific migration
docker compose exec enclava-backend alembic upgrade head

Recovery Procedures

Database Recovery:

# Stop services
docker compose stop enclava-backend

# Restore from backup
gunzip < backup/enclava_20240115.sql.gz | \
docker compose exec -T enclava-postgres psql -U enclava_user -d enclava_db

# Restart services
docker compose start enclava-backend

Complete System Recovery:

# Stop all services
docker compose down

# Restore volumes
docker volume rm enclava_enclava-postgres-data
docker volume create enclava_enclava-postgres-data

# Restore from backup and restart
docker compose up -d

--