Skip to main content

Production Setup Guide

This guide covers the complete production deployment of DeepWikiOpen, including architecture, security, monitoring, and scaling strategies.

Table of Contents

  1. Production Architecture
  2. Load Balancing & High Availability
  3. SSL/TLS Certificate Setup
  4. Reverse Proxy Configuration
  5. Security Hardening
  6. Database Optimization
  7. Monitoring & Alerting
  8. Log Management
  9. Performance Tuning
  10. Scaling Strategies
  11. Disaster Recovery
  12. CI/CD Pipeline
  13. Cloud Deployments
  14. On-Premise Setup

Production Architecture

Component Specifications

Application Servers:
  • Minimum 3 instances for high availability
  • CPU: 4+ cores per instance
  • RAM: 8GB+ per instance
  • Storage: SSD with 100GB+ per instance
Database:
  • Primary-replica configuration
  • Connection pooling enabled
  • Automated backups every 6 hours
  • Point-in-time recovery capability
Cache Layer:
  • Redis Cluster with 3+ nodes
  • Sentinel for automatic failover
  • Memory: 4GB+ per node
Load Balancer:
  • Layer 7 (HTTP/HTTPS) load balancing
  • Health check endpoints
  • SSL termination capability

Load Balancing & High Availability

HAProxy Configuration

# /etc/haproxy/haproxy.cfg
global
    daemon
    maxconn 4096
    log stdout local0
    ssl-default-bind-ciphers PROFILE=SYSTEM
    ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets

defaults
    mode http
    timeout connect 5000ms
    timeout client 50000ms
    timeout server 50000ms
    option httplog
    option dontlognull
    option redispatch
    retries 3

frontend deepwikiopen_frontend
    bind *:80
    bind *:443 ssl crt /etc/ssl/certs/deepwikiopen.pem
    redirect scheme https if !{ ssl_fc }
    
    # Security headers
    http-response set-header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
    http-response set-header X-Frame-Options "SAMEORIGIN"
    http-response set-header X-Content-Type-Options "nosniff"
    http-response set-header X-XSS-Protection "1; mode=block"
    
    # Rate limiting
    stick-table type ip size 100k expire 30s store http_req_rate(10s)
    http-request track-sc0 src
    http-request reject if { sc_http_req_rate(0) gt 20 }
    
    default_backend deepwikiopen_backend

backend deepwikiopen_backend
    balance roundrobin
    option httpchk GET /health
    http-check expect status 200
    
    server app1 10.0.1.10:3000 check inter 30s fall 3 rise 2
    server app2 10.0.1.11:3000 check inter 30s fall 3 rise 2
    server app3 10.0.1.12:3000 check inter 30s fall 3 rise 2
    server app4 10.0.1.13:3000 check inter 30s fall 3 rise 2

listen stats
    bind *:8080
    stats enable
    stats uri /stats
    stats refresh 30s
    stats admin if TRUE

Nginx Load Balancer Alternative

upstream deepwikiopen_backend {
    least_conn;
    server 10.0.1.10:3000 max_fails=3 fail_timeout=30s;
    server 10.0.1.11:3000 max_fails=3 fail_timeout=30s;
    server 10.0.1.12:3000 max_fails=3 fail_timeout=30s;
    server 10.0.1.13:3000 max_fails=3 fail_timeout=30s;
}

server {
    listen 443 ssl http2;
    server_name deepwikiopen.com;
    
    ssl_certificate /etc/ssl/certs/deepwikiopen.crt;
    ssl_certificate_key /etc/ssl/private/deepwikiopen.key;
    
    location / {
        proxy_pass http://deepwikiopen_backend;
        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;
        proxy_connect_timeout 30s;
        proxy_send_timeout 30s;
        proxy_read_timeout 30s;
    }
    
    location /health {
        access_log off;
        proxy_pass http://deepwikiopen_backend;
        proxy_connect_timeout 5s;
        proxy_read_timeout 5s;
    }
}

SSL/TLS Certificate Setup

Let’s Encrypt with Certbot

# Install certbot
sudo apt-get update
sudo apt-get install certbot python3-certbot-nginx

# Obtain certificate
sudo certbot --nginx -d deepwikiopen.com -d www.deepwikiopen.com

# Auto-renewal setup
sudo crontab -e
# Add: 0 12 * * * /usr/bin/certbot renew --quiet

Custom Certificate Setup

# Generate private key
openssl genrsa -out deepwikiopen.key 2048

# Generate certificate signing request
openssl req -new -key deepwikiopen.key -out deepwikiopen.csr

# After receiving certificate from CA
sudo mkdir -p /etc/ssl/certs /etc/ssl/private
sudo cp deepwikiopen.crt /etc/ssl/certs/
sudo cp deepwikiopen.key /etc/ssl/private/
sudo chmod 644 /etc/ssl/certs/deepwikiopen.crt
sudo chmod 600 /etc/ssl/private/deepwikiopen.key

SSL Configuration Best Practices

# Strong SSL configuration
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;

# HSTS
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;

Reverse Proxy Configuration

Nginx Reverse Proxy

# /etc/nginx/sites-available/deepwikiopen
server {
    listen 80;
    server_name deepwikiopen.com www.deepwikiopen.com;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name deepwikiopen.com www.deepwikiopen.com;
    
    # SSL Configuration
    ssl_certificate /etc/ssl/certs/deepwikiopen.crt;
    ssl_certificate_key /etc/ssl/private/deepwikiopen.key;
    include /etc/nginx/snippets/ssl-params.conf;
    
    # Security headers
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header Referrer-Policy "no-referrer-when-downgrade" always;
    add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" always;
    
    # Gzip compression
    gzip on;
    gzip_vary on;
    gzip_min_length 1024;
    gzip_types text/plain text/css text/xml text/javascript application/javascript application/xml+rss application/json;
    
    # Static files caching
    location ~* \.(jpg|jpeg|gif|png|css|js|ico|xml)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
    }
    
    # API endpoints
    location /api/ {
        proxy_pass http://localhost:3000/api/;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        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;
        proxy_cache_bypass $http_upgrade;
        
        # Rate limiting
        limit_req zone=api burst=20 nodelay;
    }
    
    # WebSocket support
    location /ws {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
    
    # Main application
    location / {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        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 check endpoint
    location /health {
        access_log off;
        proxy_pass http://localhost:3000/health;
    }
}

# Rate limiting zones
http {
    limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
    limit_req_zone $binary_remote_addr zone=general:10m rate=50r/s;
}

Apache Reverse Proxy

# Enable required modules
sudo a2enmod proxy
sudo a2enmod proxy_http
sudo a2enmod proxy_balancer
sudo a2enmod lbmethod_byrequests
sudo a2enmod headers
sudo a2enmod ssl

# Virtual host configuration
<VirtualHost *:443>
    ServerName deepwikiopen.com
    ServerAlias www.deepwikiopen.com
    
    # SSL Configuration
    SSLEngine on
    SSLCertificateFile /etc/ssl/certs/deepwikiopen.crt
    SSLCertificateKeyFile /etc/ssl/private/deepwikiopen.key
    SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
    SSLCipherSuite ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384
    
    # Security headers
    Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
    Header always set X-Frame-Options SAMEORIGIN
    Header always set X-Content-Type-Options nosniff
    
    # Proxy configuration
    ProxyPreserveHost On
    ProxyRequests Off
    
    <Proxy balancer://deepwikiopen>
        BalancerMember http://10.0.1.10:3000
        BalancerMember http://10.0.1.11:3000
        BalancerMember http://10.0.1.12:3000
        ProxySet lbmethod=byrequests
    </Proxy>
    
    ProxyPass /balancer-manager !
    ProxyPass / balancer://deepwikiopen/
    ProxyPassReverse / balancer://deepwikiopen/
    
    <Location "/balancer-manager">
        SetHandler balancer-manager
        Require ip 10.0.1.0/24
    </Location>
</VirtualHost>

Security Hardening

Environment Security Configuration

# Production environment variables
export NODE_ENV=production
export DATABASE_URL="postgresql://user:password@db-host:5432/deepwikiopen"
export REDIS_URL="redis://redis-host:6379"
export JWT_SECRET="your-super-secure-jwt-secret-here"
export ENCRYPTION_KEY="your-32-char-encryption-key-here"
export SESSION_SECRET="your-session-secret-here"
export RATE_LIMIT_MAX=100
export RATE_LIMIT_WINDOW=900000
export LOG_LEVEL=info
export TRUST_PROXY=true
export CORS_ORIGIN="https://deepwikiopen.com"

Application Security Middleware

// security.js
const helmet = require('helmet');
const rateLimit = require('express-rate-limit');
const cors = require('cors');

const securityMiddleware = (app) => {
  // Helmet for security headers
  app.use(helmet({
    contentSecurityPolicy: {
      directives: {
        defaultSrc: ["'self'"],
        scriptSrc: ["'self'", "'unsafe-inline'", "https://cdn.jsdelivr.net"],
        styleSrc: ["'self'", "'unsafe-inline'", "https://fonts.googleapis.com"],
        imgSrc: ["'self'", "data:", "https:"],
        fontSrc: ["'self'", "https://fonts.gstatic.com"],
        connectSrc: ["'self'", "wss:", "https:"],
      },
    },
    hsts: {
      maxAge: 31536000,
      includeSubDomains: true,
      preload: true
    }
  }));

  // Rate limiting
  const limiter = rateLimit({
    windowMs: 15 * 60 * 1000, // 15 minutes
    max: 100, // Limit each IP to 100 requests per windowMs
    message: 'Too many requests from this IP',
    standardHeaders: true,
    legacyHeaders: false,
  });

  const apiLimiter = rateLimit({
    windowMs: 15 * 60 * 1000,
    max: 50,
    message: 'Too many API requests from this IP',
  });

  app.use('/api/', apiLimiter);
  app.use(limiter);

  // CORS configuration
  app.use(cors({
    origin: process.env.CORS_ORIGIN || 'https://deepwikiopen.com',
    credentials: true,
    optionsSuccessStatus: 200
  }));

  // Trust proxy for accurate IP addresses
  app.set('trust proxy', process.env.TRUST_PROXY === 'true');
};

module.exports = securityMiddleware;

Firewall Configuration (UFW)

# Reset firewall
sudo ufw --force reset

# Default policies
sudo ufw default deny incoming
sudo ufw default allow outgoing

# SSH access (change port from default 22)
sudo ufw allow 2222/tcp

# HTTP/HTTPS
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

# Database (only from app servers)
sudo ufw allow from 10.0.1.0/24 to any port 5432

# Redis (only from app servers)
sudo ufw allow from 10.0.1.0/24 to any port 6379

# Monitoring
sudo ufw allow from 10.0.1.0/24 to any port 9090
sudo ufw allow from 10.0.1.0/24 to any port 3000

# Enable firewall
sudo ufw enable

Fail2Ban Configuration

# /etc/fail2ban/jail.local
[DEFAULT]
bantime = 3600
findtime = 600
maxretry = 3
backend = systemd

[sshd]
enabled = true
port = 2222
maxretry = 3

[nginx-http-auth]
enabled = true
filter = nginx-http-auth
logpath = /var/log/nginx/error.log
maxretry = 3

[nginx-req-limit]
enabled = true
filter = nginx-req-limit
logpath = /var/log/nginx/error.log
maxretry = 10
findtime = 600
bantime = 7200

Database Optimization

PostgreSQL Production Configuration

-- postgresql.conf optimizations
shared_buffers = 2GB
effective_cache_size = 6GB
maintenance_work_mem = 512MB
work_mem = 32MB
max_connections = 200
checkpoint_completion_target = 0.9
wal_buffers = 16MB
default_statistics_target = 100

-- Enable connection pooling
max_pool_size = 25
min_pool_size = 5
acquire_increment = 1
max_statements = 50
max_idle_time = 1800

Database Backup Strategy

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

BACKUP_DIR="/backup/postgresql"
DB_NAME="deepwikiopen"
DB_USER="postgres"
TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
BACKUP_FILE="${BACKUP_DIR}/${DB_NAME}_${TIMESTAMP}.sql"

# Create backup directory
mkdir -p $BACKUP_DIR

# Create database backup
pg_dump -h localhost -U $DB_USER -d $DB_NAME > $BACKUP_FILE

# Compress backup
gzip $BACKUP_FILE

# Upload to S3 (optional)
if [ "$AWS_BACKUP" = "true" ]; then
    aws s3 cp "${BACKUP_FILE}.gz" s3://deepwikiopen-backups/database/
fi

# Clean old backups (keep 30 days)
find $BACKUP_DIR -name "*.sql.gz" -mtime +30 -delete

# Verify backup integrity
if [ $? -eq 0 ]; then
    echo "Backup completed successfully: ${BACKUP_FILE}.gz"
else
    echo "Backup failed!" >&2
    exit 1
fi

Database Monitoring

-- Monitor connection usage
SELECT 
    count(*) as total_connections,
    count(*) filter (where state = 'active') as active_connections,
    count(*) filter (where state = 'idle') as idle_connections
FROM pg_stat_activity;

-- Monitor query performance
SELECT 
    query,
    calls,
    total_time,
    mean_time,
    rows
FROM pg_stat_statements
ORDER BY mean_time DESC
LIMIT 10;

-- Monitor database size
SELECT 
    pg_database.datname,
    pg_database_size(pg_database.datname) as size_bytes,
    pg_size_pretty(pg_database_size(pg_database.datname)) as size
FROM pg_database
ORDER BY size_bytes DESC;

Monitoring & Alerting

Prometheus Configuration

# prometheus.yml
global:
  scrape_interval: 15s
  evaluation_interval: 15s

rule_files:
  - "rules/*.yml"

alerting:
  alertmanagers:
    - static_configs:
        - targets:
          - alertmanager:9093

scrape_configs:
  - job_name: 'deepwikiopen'
    static_configs:
      - targets: ['localhost:3000']
    metrics_path: /metrics
    scrape_interval: 30s

  - job_name: 'node'
    static_configs:
      - targets: 
        - 'app1:9100'
        - 'app2:9100'
        - 'app3:9100'
        - 'db1:9100'
    
  - job_name: 'nginx'
    static_configs:
      - targets: ['nginx:9113']

  - job_name: 'postgresql'
    static_configs:
      - targets: ['db1:9187']

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

Grafana Dashboard Configuration

{
  "dashboard": {
    "title": "DeepWikiOpen Production Monitoring",
    "panels": [
      {
        "title": "Response Time",
        "type": "graph",
        "targets": [
          {
            "expr": "rate(http_request_duration_seconds_sum[5m]) / rate(http_request_duration_seconds_count[5m])",
            "legendFormat": "Average Response Time"
          }
        ]
      },
      {
        "title": "Request Rate",
        "type": "graph",
        "targets": [
          {
            "expr": "rate(http_requests_total[5m])",
            "legendFormat": "Requests/sec"
          }
        ]
      },
      {
        "title": "Error Rate",
        "type": "graph",
        "targets": [
          {
            "expr": "rate(http_requests_total{status=~\"5..\"}[5m])",
            "legendFormat": "5xx Errors/sec"
          }
        ]
      }
    ]
  }
}

AlertManager Rules

# rules/alerts.yml
groups:
- name: deepwikiopen
  rules:
  - alert: HighResponseTime
    expr: avg(rate(http_request_duration_seconds_sum[5m]) / rate(http_request_duration_seconds_count[5m])) > 2
    for: 5m
    labels:
      severity: warning
    annotations:
      summary: "High response time detected"
      
  - alert: HighErrorRate
    expr: rate(http_requests_total{status=~"5.."}[5m]) > 0.1
    for: 2m
    labels:
      severity: critical
    annotations:
      summary: "High error rate detected"
      
  - alert: DatabaseDown
    expr: up{job="postgresql"} == 0
    for: 1m
    labels:
      severity: critical
    annotations:
      summary: "Database is down"
      
  - alert: HighMemoryUsage
    expr: (node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes) / node_memory_MemTotal_bytes > 0.9
    for: 5m
    labels:
      severity: warning
    annotations:
      summary: "High memory usage detected"

Health Check Implementation

// health.js
const express = require('express');
const { Pool } = require('pg');
const redis = require('redis');

const router = express.Router();

const dbPool = new Pool({
  connectionString: process.env.DATABASE_URL,
});

const redisClient = redis.createClient({
  url: process.env.REDIS_URL,
});

router.get('/health', async (req, res) => {
  const health = {
    status: 'healthy',
    timestamp: new Date().toISOString(),
    services: {}
  };

  try {
    // Database health check
    const dbStart = Date.now();
    await dbPool.query('SELECT 1');
    health.services.database = {
      status: 'healthy',
      responseTime: Date.now() - dbStart
    };
  } catch (error) {
    health.status = 'unhealthy';
    health.services.database = {
      status: 'unhealthy',
      error: error.message
    };
  }

  try {
    // Redis health check
    const redisStart = Date.now();
    await redisClient.ping();
    health.services.cache = {
      status: 'healthy',
      responseTime: Date.now() - redisStart
    };
  } catch (error) {
    health.status = 'unhealthy';
    health.services.cache = {
      status: 'unhealthy',
      error: error.message
    };
  }

  // Memory check
  const memUsage = process.memoryUsage();
  health.services.memory = {
    status: memUsage.heapUsed / memUsage.heapTotal < 0.9 ? 'healthy' : 'warning',
    heapUsed: memUsage.heapUsed,
    heapTotal: memUsage.heapTotal,
    external: memUsage.external
  };

  const statusCode = health.status === 'healthy' ? 200 : 503;
  res.status(statusCode).json(health);
});

module.exports = router;

Log Management

Structured Logging Configuration

// logger.js
const winston = require('winston');
const { ElasticsearchTransport } = require('winston-elasticsearch');

const logger = winston.createLogger({
  level: process.env.LOG_LEVEL || 'info',
  format: winston.format.combine(
    winston.format.timestamp(),
    winston.format.errors({ stack: true }),
    winston.format.json()
  ),
  defaultMeta: {
    service: 'deepwikiopen',
    environment: process.env.NODE_ENV,
    version: process.env.APP_VERSION
  },
  transports: [
    new winston.transports.File({
      filename: '/var/log/deepwikiopen/error.log',
      level: 'error',
      maxsize: 10485760, // 10MB
      maxFiles: 5
    }),
    new winston.transports.File({
      filename: '/var/log/deepwikiopen/combined.log',
      maxsize: 10485760,
      maxFiles: 10
    })
  ]
});

if (process.env.NODE_ENV !== 'production') {
  logger.add(new winston.transports.Console({
    format: winston.format.simple()
  }));
}

// Elasticsearch transport for production
if (process.env.ELASTICSEARCH_URL) {
  logger.add(new ElasticsearchTransport({
    clientOpts: { node: process.env.ELASTICSEARCH_URL },
    index: 'deepwikiopen-logs'
  }));
}

module.exports = logger;

Logrotate Configuration

# /etc/logrotate.d/deepwikiopen
/var/log/deepwikiopen/*.log {
    daily
    rotate 30
    compress
    delaycompress
    missingok
    notifempty
    create 644 deepwikiopen deepwikiopen
    postrotate
        systemctl reload deepwikiopen
    endscript
}

ELK Stack Setup

# docker-compose.yml for ELK
version: '3.7'
services:
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.15.0
    environment:
      - discovery.type=single-node
      - "ES_JAVA_OPTS=-Xms1g -Xmx1g"
    volumes:
      - elasticsearch_data:/usr/share/elasticsearch/data
    ports:
      - "9200:9200"

  logstash:
    image: docker.elastic.co/logstash/logstash:7.15.0
    volumes:
      - ./logstash.conf:/usr/share/logstash/pipeline/logstash.conf
    depends_on:
      - elasticsearch

  kibana:
    image: docker.elastic.co/kibana/kibana:7.15.0
    environment:
      - ELASTICSEARCH_HOSTS=http://elasticsearch:9200
    ports:
      - "5601:5601"
    depends_on:
      - elasticsearch

volumes:
  elasticsearch_data:

Performance Tuning

Application Performance Optimization

// performance.js
const compression = require('compression');
const responseTime = require('response-time');
const cluster = require('cluster');
const numCPUs = require('os').cpus().length;

// Cluster setup for production
if (cluster.isMaster && process.env.NODE_ENV === 'production') {
  console.log(`Master ${process.pid} is running`);
  
  // Fork workers
  for (let i = 0; i < numCPUs; i++) {
    cluster.fork();
  }
  
  cluster.on('exit', (worker, code, signal) => {
    console.log(`Worker ${worker.process.pid} died`);
    cluster.fork();
  });
} else {
  const express = require('express');
  const app = express();
  
  // Performance middleware
  app.use(compression({
    filter: (req, res) => {
      if (req.headers['x-no-compression']) {
        return false;
      }
      return compression.filter(req, res);
    },
    level: 6,
    threshold: 1024
  }));
  
  app.use(responseTime((req, res, time) => {
    console.log(`${req.method} ${req.url} - ${time}ms`);
  }));
  
  // Connection pooling
  const { Pool } = require('pg');
  const pool = new Pool({
    connectionString: process.env.DATABASE_URL,
    max: 20,
    idleTimeoutMillis: 30000,
    connectionTimeoutMillis: 2000,
  });
  
  // Cache configuration
  const NodeCache = require('node-cache');
  const cache = new NodeCache({
    stdTTL: 600, // 10 minutes
    checkperiod: 120,
    useClones: false
  });
  
  // Caching middleware
  const cacheMiddleware = (duration) => {
    return (req, res, next) => {
      const key = req.originalUrl || req.url;
      const cached = cache.get(key);
      
      if (cached) {
        return res.json(cached);
      }
      
      res.sendResponse = res.json;
      res.json = (body) => {
        cache.set(key, body, duration);
        res.sendResponse(body);
      };
      
      next();
    };
  };
  
  app.use('/api/search', cacheMiddleware(300)); // 5 minutes cache
  
  console.log(`Worker ${process.pid} started`);
}

Database Query Optimization

-- Create appropriate indexes
CREATE INDEX CONCURRENTLY idx_articles_title_search ON articles USING gin(to_tsvector('english', title));
CREATE INDEX CONCURRENTLY idx_articles_content_search ON articles USING gin(to_tsvector('english', content));
CREATE INDEX CONCURRENTLY idx_articles_created_at ON articles(created_at DESC);
CREATE INDEX CONCURRENTLY idx_articles_category ON articles(category_id);

-- Partitioning for large tables
CREATE TABLE articles_2023 PARTITION OF articles
    FOR VALUES FROM ('2023-01-01') TO ('2024-01-01');

-- Query optimization examples
EXPLAIN ANALYZE SELECT * FROM articles 
WHERE to_tsvector('english', title || ' ' || content) @@ to_tsquery('search_term')
ORDER BY created_at DESC 
LIMIT 20;

-- Connection pooling settings
ALTER SYSTEM SET max_connections = 200;
ALTER SYSTEM SET shared_buffers = '2GB';
ALTER SYSTEM SET effective_cache_size = '6GB';
SELECT pg_reload_conf();

Redis Cache Optimization

// cache.js
const redis = require('redis');
const { promisify } = require('util');

class CacheManager {
  constructor() {
    this.client = redis.createClient({
      url: process.env.REDIS_URL,
      retry_strategy: (options) => {
        if (options.error && options.error.code === 'ECONNREFUSED') {
          return new Error('Redis server connection refused');
        }
        if (options.total_retry_time > 1000 * 60 * 60) {
          return new Error('Retry time exhausted');
        }
        if (options.attempt > 10) {
          return undefined;
        }
        return Math.min(options.attempt * 100, 3000);
      }
    });
    
    this.getAsync = promisify(this.client.get).bind(this.client);
    this.setAsync = promisify(this.client.set).bind(this.client);
    this.delAsync = promisify(this.client.del).bind(this.client);
  }
  
  async get(key) {
    try {
      const result = await this.getAsync(key);
      return result ? JSON.parse(result) : null;
    } catch (error) {
      console.error('Cache get error:', error);
      return null;
    }
  }
  
  async set(key, value, ttl = 3600) {
    try {
      await this.setAsync(key, JSON.stringify(value), 'EX', ttl);
      return true;
    } catch (error) {
      console.error('Cache set error:', error);
      return false;
    }
  }
  
  async invalidate(pattern) {
    try {
      const keys = await this.client.keys(pattern);
      if (keys.length > 0) {
        await this.delAsync(keys);
      }
      return true;
    } catch (error) {
      console.error('Cache invalidate error:', error);
      return false;
    }
  }
}

module.exports = new CacheManager();

Scaling Strategies

Horizontal Scaling Setup

# kubernetes deployment
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deepwikiopen
spec:
  replicas: 4
  selector:
    matchLabels:
      app: deepwikiopen
  template:
    metadata:
      labels:
        app: deepwikiopen
    spec:
      containers:
      - name: deepwikiopen
        image: deepwikiopen:latest
        ports:
        - containerPort: 3000
        env:
        - name: NODE_ENV
          value: "production"
        - name: DATABASE_URL
          valueFrom:
            secretKeyRef:
              name: db-secret
              key: url
        resources:
          requests:
            memory: "512Mi"
            cpu: "250m"
          limits:
            memory: "1Gi"
            cpu: "500m"
        livenessProbe:
          httpGet:
            path: /health
            port: 3000
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /ready
            port: 3000
          initialDelaySeconds: 5
          periodSeconds: 5

---
apiVersion: v1
kind: Service
metadata:
  name: deepwikiopen-service
spec:
  selector:
    app: deepwikiopen
  ports:
  - port: 80
    targetPort: 3000
  type: LoadBalancer

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

Auto-scaling Scripts

#!/bin/bash
# auto-scale.sh

CURRENT_LOAD=$(uptime | awk -F'load average:' '{ print $2 }' | cut -d, -f1 | tr -d ' ')
CPU_CORES=$(nproc)
THRESHOLD=$(echo "$CPU_CORES * 0.8" | bc)

if (( $(echo "$CURRENT_LOAD > $THRESHOLD" | bc -l) )); then
    echo "High load detected: $CURRENT_LOAD"
    # Scale up
    docker-compose up -d --scale deepwikiopen=6
    
    # Update load balancer
    sudo systemctl reload nginx
    
    echo "Scaled up to 6 instances"
elif (( $(echo "$CURRENT_LOAD < $(echo "$THRESHOLD * 0.5" | bc)" | bc -l) )); then
    echo "Low load detected: $CURRENT_LOAD"
    # Scale down
    docker-compose up -d --scale deepwikiopen=2
    
    echo "Scaled down to 2 instances"
fi

Database Read Replica Setup

-- On primary database
ALTER SYSTEM SET wal_level = replica;
ALTER SYSTEM SET max_wal_senders = 3;
ALTER SYSTEM SET max_replication_slots = 3;
SELECT pg_reload_conf();

-- Create replication user
CREATE USER replicator REPLICATION LOGIN CONNECTION LIMIT 1 ENCRYPTED PASSWORD 'secure_password';

-- On replica server
pg_basebackup -h primary-server -D /var/lib/postgresql/12/main -U replicator -v -P -W

-- recovery.conf on replica
standby_mode = 'on'
primary_conninfo = 'host=primary-server port=5432 user=replicator'
trigger_file = '/tmp/postgresql.trigger'

Disaster Recovery

Backup Strategy

#!/bin/bash
# disaster-recovery-backup.sh

BACKUP_ROOT="/backup"
S3_BUCKET="deepwikiopen-disaster-recovery"
DATE=$(date +%Y%m%d_%H%M%S)

# Database backup
pg_dump -h localhost -U postgres deepwikiopen | gzip > "$BACKUP_ROOT/database_$DATE.sql.gz"

# Application files backup
tar -czf "$BACKUP_ROOT/application_$DATE.tar.gz" /var/www/deepwikiopen

# Configuration backup
tar -czf "$BACKUP_ROOT/config_$DATE.tar.gz" /etc/nginx /etc/ssl

# Upload to S3
aws s3 sync $BACKUP_ROOT s3://$S3_BUCKET/backups/$DATE/

# Create disaster recovery snapshot
aws ec2 create-snapshot --volume-id vol-1234567890abcdef0 --description "DR backup $DATE"

# Test backup integrity
gunzip -t "$BACKUP_ROOT/database_$DATE.sql.gz"
if [ $? -eq 0 ]; then
    echo "Database backup verified successfully"
else
    echo "Database backup verification failed!" >&2
    exit 1
fi

# Clean old backups (keep 30 days)
find $BACKUP_ROOT -name "*.gz" -mtime +30 -delete
aws s3api list-objects-v2 --bucket $S3_BUCKET --query "Contents[?LastModified<='$(date -d '30 days ago' -I)'].Key" --output text | xargs -I {} aws s3 rm s3://$S3_BUCKET/{}

Recovery Procedures

#!/bin/bash
# disaster-recovery-restore.sh

BACKUP_DATE=$1
S3_BUCKET="deepwikiopen-disaster-recovery"

if [ -z "$BACKUP_DATE" ]; then
    echo "Usage: $0 YYYYMMDD_HHMMSS"
    exit 1
fi

echo "Starting disaster recovery for backup: $BACKUP_DATE"

# Download backups from S3
aws s3 sync s3://$S3_BUCKET/backups/$BACKUP_DATE/ /tmp/restore/

# Stop application
sudo systemctl stop deepwikiopen
sudo systemctl stop nginx

# Restore database
sudo -u postgres dropdb deepwikiopen
sudo -u postgres createdb deepwikiopen
gunzip -c /tmp/restore/database_$BACKUP_DATE.sql.gz | sudo -u postgres psql deepwikiopen

# Restore application files
tar -xzf /tmp/restore/application_$BACKUP_DATE.tar.gz -C /

# Restore configuration
tar -xzf /tmp/restore/config_$BACKUP_DATE.tar.gz -C /

# Verify restoration
sudo -u postgres psql deepwikiopen -c "SELECT COUNT(*) FROM articles;"

# Start services
sudo systemctl start deepwikiopen
sudo systemctl start nginx

# Verify application is working
curl -f http://localhost/health || {
    echo "Health check failed after restoration!"
    exit 1
}

echo "Disaster recovery completed successfully"

RTO/RPO Documentation

# disaster-recovery-plan.yml
recovery_objectives:
  rpo: 1_hour  # Recovery Point Objective
  rto: 4_hours # Recovery Time Objective

backup_schedule:
  database:
    full: "0 2 * * 0"    # Weekly full backup
    incremental: "0 */6 * * *" # Every 6 hours
  
  application:
    frequency: "0 1 * * *" # Daily
    
  configuration:
    frequency: "0 3 * * 1" # Weekly

recovery_procedures:
  - verify_backup_integrity
  - provision_infrastructure
  - restore_database
  - restore_application
  - restore_configuration
  - verify_functionality
  - update_dns
  - notify_stakeholders

contacts:
  primary: "ops-team@company.com"
  backup: "cto@company.com"
  escalation: "ceo@company.com"

CI/CD Pipeline

GitHub Actions Workflow

# .github/workflows/production-deploy.yml
name: Production Deploy

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

env:
  NODE_VERSION: '18.x'
  REGISTRY: ghcr.io
  IMAGE_NAME: deepwikiopen

jobs:
  test:
    runs-on: ubuntu-latest
    
    services:
      postgres:
        image: postgres:13
        env:
          POSTGRES_PASSWORD: postgres
          POSTGRES_DB: deepwikiopen_test
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
        ports:
          - 5432:5432
      
      redis:
        image: redis:6
        options: >-
          --health-cmd "redis-cli ping"
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
        ports:
          - 6379:6379

    steps:
    - uses: actions/checkout@v3
    
    - name: Setup Node.js
      uses: actions/setup-node@v3
      with:
        node-version: ${{ env.NODE_VERSION }}
        cache: 'npm'
    
    - name: Install dependencies
      run: npm ci
    
    - name: Run linting
      run: npm run lint
    
    - name: Run type checking
      run: npm run typecheck
    
    - name: Run tests
      run: npm test
      env:
        DATABASE_URL: postgresql://postgres:postgres@localhost:5432/deepwikiopen_test
        REDIS_URL: redis://localhost:6379
    
    - name: Run integration tests
      run: npm run test:integration
      env:
        DATABASE_URL: postgresql://postgres:postgres@localhost:5432/deepwikiopen_test
        REDIS_URL: redis://localhost:6379

  security-scan:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3
    
    - name: Run security audit
      run: npm audit --audit-level high
    
    - name: Run Snyk security scan
      uses: snyk/actions/node@master
      env:
        SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}

  build:
    needs: [test, security-scan]
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v3
    
    - name: Setup Docker Buildx
      uses: docker/setup-buildx-action@v2
    
    - name: Login to Container Registry
      uses: docker/login-action@v2
      with:
        registry: ${{ env.REGISTRY }}
        username: ${{ github.actor }}
        password: ${{ secrets.GITHUB_TOKEN }}
    
    - name: Extract metadata
      id: meta
      uses: docker/metadata-action@v4
      with:
        images: ${{ env.REGISTRY }}/${{ github.repository }}/${{ env.IMAGE_NAME }}
        tags: |
          type=ref,event=branch
          type=ref,event=pr
          type=sha,prefix=sha-
    
    - name: Build and push Docker image
      uses: docker/build-push-action@v4
      with:
        context: .
        file: ./Dockerfile.production
        push: true
        tags: ${{ steps.meta.outputs.tags }}
        labels: ${{ steps.meta.outputs.labels }}
        cache-from: type=gha
        cache-to: type=gha,mode=max

  deploy-staging:
    needs: build
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'
    environment: staging
    
    steps:
    - name: Deploy to staging
      run: |
        # Deploy to staging environment
        echo "Deploying to staging..."
        # Add your staging deployment commands here

  deploy-production:
    needs: [build, deploy-staging]
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'
    environment: production
    
    steps:
    - name: Deploy to production
      run: |
        # Deploy to production environment
        echo "Deploying to production..."
        # Add your production deployment commands here
    
    - name: Run smoke tests
      run: |
        # Run post-deployment smoke tests
        curl -f https://deepwikiopen.com/health
        curl -f https://deepwikiopen.com/api/health

Production Dockerfile

# Dockerfile.production
FROM node:18-alpine AS builder

WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production && npm cache clean --force

COPY . .
RUN npm run build

FROM node:18-alpine AS production

RUN addgroup -g 1001 -S nodejs
RUN adduser -S deepwikiopen -u 1001

WORKDIR /app

COPY --from=builder --chown=deepwikiopen:nodejs /app/dist ./dist
COPY --from=builder --chown=deepwikiopen:nodejs /app/node_modules ./node_modules
COPY --from=builder --chown=deepwikiopen:nodejs /app/package.json ./package.json

USER deepwikiopen

EXPOSE 3000

ENV NODE_ENV=production
ENV PORT=3000

HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
  CMD node healthcheck.js

CMD ["node", "dist/server.js"]

Cloud Deployments

AWS Deployment

ECS with Fargate

# aws-ecs-task-definition.json
{
  "family": "deepwikiopen-production",
  "networkMode": "awsvpc",
  "requiresCompatibilities": ["FARGATE"],
  "cpu": "1024",
  "memory": "2048",
  "executionRoleArn": "arn:aws:iam::123456789012:role/ecsTaskExecutionRole",
  "taskRoleArn": "arn:aws:iam::123456789012:role/deepwikiopenTaskRole",
  "containerDefinitions": [
    {
      "name": "deepwikiopen",
      "image": "123456789012.dkr.ecr.us-east-1.amazonaws.com/deepwikiopen:latest",
      "portMappings": [
        {
          "containerPort": 3000,
          "protocol": "tcp"
        }
      ],
      "environment": [
        {
          "name": "NODE_ENV",
          "value": "production"
        }
      ],
      "secrets": [
        {
          "name": "DATABASE_URL",
          "valueFrom": "arn:aws:secretsmanager:us-east-1:123456789012:secret:deepwikiopen/database-url"
        }
      ],
      "logConfiguration": {
        "logDriver": "awslogs",
        "options": {
          "awslogs-group": "/ecs/deepwikiopen",
          "awslogs-region": "us-east-1",
          "awslogs-stream-prefix": "ecs"
        }
      },
      "healthCheck": {
        "command": ["CMD-SHELL", "curl -f http://localhost:3000/health || exit 1"],
        "interval": 30,
        "timeout": 5,
        "retries": 3,
        "startPeriod": 60
      }
    }
  ]
}

Terraform Infrastructure

# aws-infrastructure.tf
provider "aws" {
  region = "us-east-1"
}

# VPC
resource "aws_vpc" "main" {
  cidr_block           = "10.0.0.0/16"
  enable_dns_hostnames = true
  enable_dns_support   = true
  
  tags = {
    Name = "deepwikiopen-vpc"
  }
}

# Internet Gateway
resource "aws_internet_gateway" "main" {
  vpc_id = aws_vpc.main.id
  
  tags = {
    Name = "deepwikiopen-igw"
  }
}

# Subnets
resource "aws_subnet" "public" {
  count             = 2
  vpc_id            = aws_vpc.main.id
  cidr_block        = "10.0.${count.index + 1}.0/24"
  availability_zone = data.aws_availability_zones.available.names[count.index]
  
  map_public_ip_on_launch = true
  
  tags = {
    Name = "deepwikiopen-public-${count.index + 1}"
  }
}

resource "aws_subnet" "private" {
  count             = 2
  vpc_id            = aws_vpc.main.id
  cidr_block        = "10.0.${count.index + 10}.0/24"
  availability_zone = data.aws_availability_zones.available.names[count.index]
  
  tags = {
    Name = "deepwikiopen-private-${count.index + 1}"
  }
}

# RDS Database
resource "aws_db_instance" "main" {
  identifier             = "deepwikiopen-db"
  engine                 = "postgres"
  engine_version         = "13.7"
  instance_class         = "db.t3.medium"
  allocated_storage      = 100
  max_allocated_storage  = 1000
  
  db_name  = "deepwikiopen"
  username = var.db_username
  password = var.db_password
  
  vpc_security_group_ids = [aws_security_group.rds.id]
  db_subnet_group_name   = aws_db_subnet_group.main.name
  
  backup_retention_period = 30
  backup_window          = "03:00-04:00"
  maintenance_window     = "sun:04:00-sun:05:00"
  
  skip_final_snapshot = false
  final_snapshot_identifier = "deepwikiopen-final-snapshot"
  
  tags = {
    Name = "deepwikiopen-database"
  }
}

# ElastiCache Redis
resource "aws_elasticache_subnet_group" "main" {
  name       = "deepwikiopen-cache-subnet"
  subnet_ids = aws_subnet.private[*].id
}

resource "aws_elasticache_replication_group" "main" {
  replication_group_id         = "deepwikiopen-redis"
  description                  = "Redis cluster for DeepWikiOpen"
  
  node_type                    = "cache.t3.micro"
  port                         = 6379
  parameter_group_name         = "default.redis6.x"
  
  num_cache_clusters           = 2
  automatic_failover_enabled   = true
  multi_az_enabled            = true
  
  subnet_group_name           = aws_elasticache_subnet_group.main.name
  security_group_ids          = [aws_security_group.redis.id]
  
  at_rest_encryption_enabled  = true
  transit_encryption_enabled  = true
  auth_token                  = var.redis_auth_token
  
  tags = {
    Name = "deepwikiopen-redis"
  }
}

# Application Load Balancer
resource "aws_lb" "main" {
  name               = "deepwikiopen-alb"
  internal           = false
  load_balancer_type = "application"
  security_groups    = [aws_security_group.alb.id]
  subnets            = aws_subnet.public[*].id
  
  enable_deletion_protection = true
  
  tags = {
    Name = "deepwikiopen-alb"
  }
}

# ECS Cluster
resource "aws_ecs_cluster" "main" {
  name = "deepwikiopen"
  
  capacity_providers = ["FARGATE"]
  
  default_capacity_provider_strategy {
    capacity_provider = "FARGATE"
    weight           = 1
  }
  
  setting {
    name  = "containerInsights"
    value = "enabled"
  }
  
  tags = {
    Name = "deepwikiopen-cluster"
  }
}

Google Cloud Platform Deployment

# gcp-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deepwikiopen
  namespace: production
spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
  selector:
    matchLabels:
      app: deepwikiopen
  template:
    metadata:
      labels:
        app: deepwikiopen
    spec:
      containers:
      - name: deepwikiopen
        image: gcr.io/your-project/deepwikiopen:latest
        ports:
        - containerPort: 3000
        env:
        - name: NODE_ENV
          value: "production"
        - name: DATABASE_URL
          valueFrom:
            secretKeyRef:
              name: app-secrets
              key: database-url
        - name: REDIS_URL
          valueFrom:
            secretKeyRef:
              name: app-secrets
              key: redis-url
        resources:
          requests:
            memory: "512Mi"
            cpu: "250m"
          limits:
            memory: "1Gi"
            cpu: "500m"
        livenessProbe:
          httpGet:
            path: /health
            port: 3000
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /ready
            port: 3000
          initialDelaySeconds: 5
          periodSeconds: 5

---
apiVersion: v1
kind: Service
metadata:
  name: deepwikiopen-service
  namespace: production
spec:
  selector:
    app: deepwikiopen
  ports:
  - port: 80
    targetPort: 3000
  type: LoadBalancer

---
apiVersion: networking.gke.io/v1
kind: ManagedCertificate
metadata:
  name: deepwikiopen-ssl-cert
  namespace: production
spec:
  domains:
    - deepwikiopen.com
    - www.deepwikiopen.com

---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: deepwikiopen-ingress
  namespace: production
  annotations:
    kubernetes.io/ingress.global-static-ip-name: deepwikiopen-ip
    networking.gke.io/managed-certificates: deepwikiopen-ssl-cert
    kubernetes.io/ingress.class: "gce"
spec:
  rules:
  - host: deepwikiopen.com
    http:
      paths:
      - path: /*
        pathType: ImplementationSpecific
        backend:
          service:
            name: deepwikiopen-service
            port:
              number: 80

Azure Deployment

# azure-container-instances.yaml
apiVersion: 2019-12-01
location: eastus
name: deepwikiopen-container-group
properties:
  containers:
  - name: deepwikiopen
    properties:
      image: your-registry.azurecr.io/deepwikiopen:latest
      resources:
        requests:
          cpu: 2
          memoryInGB: 4
      ports:
      - port: 3000
        protocol: TCP
      environmentVariables:
      - name: NODE_ENV
        value: production
      - name: DATABASE_URL
        secureValue: your-database-connection-string
      - name: REDIS_URL
        secureValue: your-redis-connection-string
  osType: Linux
  restartPolicy: Always
  ipAddress:
    type: Public
    ports:
    - protocol: tcp
      port: 3000
    dnsNameLabel: deepwikiopen
  sku: Standard
tags:
  environment: production
  application: deepwikiopen

On-Premise Setup

Server Requirements

# System requirements
CPU: 8+ cores
RAM: 16GB+ 
Storage: 500GB+ SSD
Network: 1Gbps+
OS: Ubuntu 20.04 LTS or CentOS 8

# Install prerequisites
sudo apt update
sudo apt install -y nodejs npm nginx postgresql redis-server

# Install Docker
curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh
sudo usermod -aG docker $USER

# Install Docker Compose
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose

Docker Compose Production Setup

# docker-compose.production.yml
version: '3.8'

services:
  app:
    build:
      context: .
      dockerfile: Dockerfile.production
    deploy:
      replicas: 4
      resources:
        limits:
          cpus: '1.0'
          memory: 1G
        reservations:
          cpus: '0.5'
          memory: 512M
    environment:
      - NODE_ENV=production
      - DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@db:5432/deepwikiopen
      - REDIS_URL=redis://redis:6379
    depends_on:
      - db
      - redis
    networks:
      - deepwikiopen-network

  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
      - ./ssl:/etc/nginx/ssl:ro
    depends_on:
      - app
    networks:
      - deepwikiopen-network

  db:
    image: postgres:13
    environment:
      - POSTGRES_DB=deepwikiopen
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
    volumes:
      - postgres_data:/var/lib/postgresql/data
      - ./backups:/backups
    networks:
      - deepwikiopen-network
    deploy:
      resources:
        limits:
          cpus: '2.0'
          memory: 4G

  redis:
    image: redis:6-alpine
    command: redis-server --appendonly yes --requirepass ${REDIS_PASSWORD}
    volumes:
      - redis_data:/data
    networks:
      - deepwikiopen-network

  prometheus:
    image: prom/prometheus
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
      - prometheus_data:/prometheus
    networks:
      - deepwikiopen-network

  grafana:
    image: grafana/grafana
    ports:
      - "3000:3000"
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD}
    volumes:
      - grafana_data:/var/lib/grafana
    networks:
      - deepwikiopen-network

volumes:
  postgres_data:
  redis_data:
  prometheus_data:
  grafana_data:

networks:
  deepwikiopen-network:
    driver: bridge

Production Environment Configuration

# .env.production
NODE_ENV=production
PORT=3000

# Database
DATABASE_URL=postgresql://postgres:secure_password@localhost:5432/deepwikiopen
DB_POOL_SIZE=25

# Redis
REDIS_URL=redis://localhost:6379
REDIS_PASSWORD=secure_redis_password

# Security
JWT_SECRET=your-super-secure-jwt-secret-minimum-32-characters
SESSION_SECRET=your-session-secret-minimum-32-characters
ENCRYPTION_KEY=your-32-character-encryption-key

# Logging
LOG_LEVEL=info
LOG_FILE_PATH=/var/log/deepwikiopen/app.log

# Performance
CLUSTER_ENABLED=true
CACHE_TTL=3600
COMPRESSION_ENABLED=true

# Monitoring
PROMETHEUS_ENABLED=true
HEALTH_CHECK_INTERVAL=30

# Email (for notifications)
SMTP_HOST=smtp.example.com
SMTP_PORT=587
SMTP_USER=notifications@deepwikiopen.com
SMTP_PASS=smtp_password

# External Services
CDN_URL=https://cdn.deepwikiopen.com
ANALYTICS_ID=your-analytics-id
This comprehensive production setup guide covers all aspects of deploying DeepWikiOpen in a production environment, from basic architecture to advanced scaling and disaster recovery strategies. Choose the deployment method that best fits your infrastructure requirements and scale accordingly.