adi-o3-multipass/deployment_instructions.md

19 KiB

Enhanced Brief Processing System - Production Deployment Guide

Overview

This guide provides complete instructions for deploying the Enhanced Brief Processing System on an Ubuntu web server. The system consists of a React frontend and Python backend with real-time WebSocket communication.

Architecture: React Frontend → Apache Proxy → Python Backend (Quart/WebSocket) → AI Services

Prerequisites

System Requirements

  • OS: Ubuntu 20.04 LTS or newer
  • CPU: 4+ cores (8+ recommended for production)
  • RAM: 8GB minimum (16GB+ recommended)
  • Storage: 100GB+ SSD with high IOPS
  • Network: Stable internet connection for AI API calls

Required Software

# Update system packages
sudo apt update && sudo apt upgrade -y

# Install essential packages
sudo apt install -y python3.11 python3.11-venv python3.11-dev python3-pip
sudo apt install -y nodejs npm apache2 git curl wget unzip
sudo apt install -y build-essential libffi-dev libssl-dev

# Enable Apache modules
sudo a2enmod proxy proxy_http proxy_wstunnel rewrite ssl headers

Required API Keys

Before deployment, ensure you have:

  • OpenAI API Key (for GPT-5 access)
  • Anthropic API Key (for Claude models)
  • Google AI API Key (for Gemini 2.5 Pro)
  • LlamaCloud API Key (for document parsing)
  • Microsoft Azure AD App Registration (for production authentication)

Step 1: Prepare Deployment Files

1.1 Create Deployment Directory

# Create deployment directory
sudo mkdir -p /var/www/html/brief-extractor
sudo chown -R $USER:www-data /var/www/html/brief-extractor
sudo chmod -R 755 /var/www/html/brief-extractor

1.2 Build Frontend

On your development machine:

# Navigate to frontend directory
cd frontend

# Set production environment
echo "VITE_API_BASE_URL=/api" > .env.production

# Build for production
npm ci
npm run build

# The built files will be in frontend/dist/

1.3 Copy Files to Server

Frontend Files (copy contents of frontend/dist/ to server):

# On your local machine, create deployment package
cd frontend/dist
tar -czf frontend-dist.tar.gz *

# Copy to server
scp frontend-dist.tar.gz user@your-server:/tmp/

# On server, extract frontend files
cd /var/www/html/brief-extractor
sudo tar -xzf /tmp/frontend-dist.tar.gz
sudo chown -R www-data:www-data /var/www/html/brief-extractor

Backend Files (copy these directories/files to server):

# Create backend directory
sudo mkdir -p /var/www/html/brief-extractor/backend
cd /var/www/html/brief-extractor/backend

# Copy these files/directories from your project:
# - core/ (entire directory)
# - server/ (entire directory)
# - prompts/ (entire directory)
# - run_server.py
# - requirements_enhanced.txt
# - server_requirements.txt
# - .env.example (rename to .env and configure)

# Example rsync command (adjust paths as needed):
rsync -av --exclude='venv' --exclude='node_modules' --exclude='frontend' --exclude='output' --exclude='__pycache__' /path/to/your/project/ user@your-server:/var/www/html/brief-extractor/backend/

Step 2: Backend Setup

2.1 Create Python Virtual Environment

cd /var/www/html/brief-extractor/backend

# Create virtual environment
python3.11 -m venv venv

# Activate virtual environment
source venv/bin/activate

# Upgrade pip
pip install --upgrade pip setuptools wheel

2.2 Install Python Dependencies

# Install core dependencies
pip install -r requirements_enhanced.txt

# Install web server dependencies
pip install -r server_requirements.txt

# Verify installation
python -c "import quart, anthropic, openai; print('Dependencies installed successfully')"

2.3 Configure Environment Variables

# Copy and edit environment file
cp .env.example .env
sudo nano .env

Production .env Configuration:

# Production Mode Settings
DEV_MODE=false
DEBUG=false
ENVIRONMENT=production

# Server Configuration
SERVER_HOST=127.0.0.1
SERVER_PORT=8000
SERVER_WORKERS=4

# Security Settings
SESSION_SECRET=your-cryptographically-strong-secret-here-min-32-chars
SECURE_COOKIES=true
CORS_ALLOWED_ORIGINS=https://yourdomain.com,https://www.yourdomain.com

# API Keys (REQUIRED)
OPENAI_API_KEY=sk-your-openai-api-key-here
ANTHROPIC_API_KEY=sk-ant-your-anthropic-api-key-here
GOOGLE_API_KEY=AIzaSy-your-google-api-key-here
LLAMACLOUD_API_KEY=llx-your-llamacloud-api-key-here

# Model Configuration
OPENAI_REASONING_EFFORT=medium
ANTHROPIC_MAX_TOKENS=64000
GOOGLE_MAX_OUTPUT_TOKENS=100000

# Processing Settings
DEFAULT_PRIMARY_MODELS=openai-gpt5,anthropic-sonnet4,google-gemini25
DEFAULT_CONSOLIDATION_MODEL=openai-gpt5
MAX_PROCESSING_COST_USD=10.00
MAX_CONCURRENT_JOBS=3
MAX_UPLOAD_SIZE_MB=200
FILE_RETENTION_HOURS=24

# Microsoft Azure AD (Production Authentication)
MSAL_CLIENT_ID=your-azure-app-client-id
MSAL_CLIENT_SECRET=your-azure-app-client-secret
MSAL_TENANT_ID=your-azure-tenant-id
MSAL_AUTHORITY=https://login.microsoftonline.com/your-tenant-id
MSAL_REDIRECT_URI=https://yourdomain.com/auth/callback

# Logging
LOG_LEVEL=INFO
LOG_FILE=/var/log/brief-extractor/app.log

2.4 Create Required Directories

# Create data directories
sudo mkdir -p /var/www/html/brief-extractor/backend/server/data/{uploads,outputs}
sudo mkdir -p /var/log/brief-extractor

# Set permissions
sudo chown -R $USER:www-data /var/www/html/brief-extractor/backend/server/data
sudo chmod -R 775 /var/www/html/brief-extractor/backend/server/data
sudo chown -R $USER:adm /var/log/brief-extractor
sudo chmod -R 755 /var/log/brief-extractor

2.5 Test Backend Installation

# Test the backend can start
cd /var/www/html/brief-extractor/backend
source venv/bin/activate
python -c "from server.app import create_app; print('Backend setup successful')"

Step 3: Create Systemd Service

3.1 Create Service File

sudo nano /etc/systemd/system/brief-extractor.service

Service Configuration:

[Unit]
Description=Enhanced Brief Processing System Backend
After=network.target
Wants=network-online.target

[Service]
Type=exec
User=www-data
Group=www-data
WorkingDirectory=/var/www/html/brief-extractor/backend
Environment=PATH=/var/www/html/brief-extractor/backend/venv/bin
EnvironmentFile=/var/www/html/brief-extractor/backend/.env
ExecStart=/var/www/html/brief-extractor/backend/venv/bin/python run_server.py
ExecReload=/bin/kill -HUP $MAINPID
KillMode=mixed
TimeoutStopSec=5
PrivateTmp=true
Restart=on-failure
RestartSec=10

# Security settings
NoNewPrivileges=yes
ProtectSystem=strict
ProtectHome=yes
ReadWritePaths=/var/www/html/brief-extractor/backend/server/data /var/log/brief-extractor /tmp

# Resource limits
LimitNOFILE=65536
LimitNPROC=4096

[Install]
WantedBy=multi-user.target

3.2 Configure Service Permissions

# Set proper ownership
sudo chown -R www-data:www-data /var/www/html/brief-extractor/backend
sudo chmod +x /var/www/html/brief-extractor/backend/run_server.py

# Reload systemd
sudo systemctl daemon-reload

# Enable service to start on boot
sudo systemctl enable brief-extractor.service

Step 4: Configure Apache Reverse Proxy

4.1 Configure Apache

sudo nano /etc/apache2/apache2.conf

Add this configuration to /etc/apache2/apache2.conf:

# Brief Extractor Virtual Host Configuration
<VirtualHost *:80>
    ServerName yourdomain.com
    ServerAlias www.yourdomain.com
    DocumentRoot /var/www/html/brief-extractor

    # Redirect HTTP to HTTPS
    RewriteEngine On
    RewriteCond %{HTTPS} off
    RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</VirtualHost>

<VirtualHost *:443>
    ServerName yourdomain.com
    ServerAlias www.yourdomain.com
    DocumentRoot /var/www/html/brief-extractor

    # SSL Configuration (configure with your certificates)
    SSLEngine on
    SSLCertificateFile /path/to/your/certificate.crt
    SSLCertificateKeyFile /path/to/your/private.key
    SSLCertificateChainFile /path/to/your/chain.crt

    # Security Headers
    Header always set X-Content-Type-Options nosniff
    Header always set X-Frame-Options DENY
    Header always set X-XSS-Protection "1; mode=block"
    Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
    Header always set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; connect-src 'self' wss://yourdomain.com https://api.openai.com https://api.anthropic.com https://generativelanguage.googleapis.com"

    # Static files (React frontend)
    <Directory /var/www/html/brief-extractor>
        Options -Indexes +FollowSymLinks
        AllowOverride None
        Require all granted

        # Handle React Router (SPA)
        RewriteEngine On
        RewriteBase /
        RewriteRule ^index\.html$ - [L]
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteCond %{REQUEST_FILENAME} !-d
        RewriteCond %{REQUEST_URI} !^/api
        RewriteCond %{REQUEST_URI} !^/ws
        RewriteRule . /index.html [L]
    </Directory>

    # Proxy API requests to backend
    ProxyPreserveHost On
    ProxyRequests Off

    # API endpoints
    ProxyPass /api/ http://127.0.0.1:8000/api/
    ProxyPassReverse /api/ http://127.0.0.1:8000/api/

    # Health check endpoint
    ProxyPass /health http://127.0.0.1:8000/health
    ProxyPassReverse /health http://127.0.0.1:8000/health

    # WebSocket proxy
    ProxyPass /ws/ ws://127.0.0.1:8000/ws/
    ProxyPassReverse /ws/ ws://127.0.0.1:8000/ws/

    # Logging
    ErrorLog ${APACHE_LOG_DIR}/brief-extractor_error.log
    CustomLog ${APACHE_LOG_DIR}/brief-extractor_access.log combined

    # Optional: Rate limiting (requires mod_evasive)
    # DOSHashTableSize    32768
    # DOSPageCount        10
    # DOSPageInterval     2
    # DOSSiteCount        50
    # DOSSiteInterval     2
    # DOSBlockingPeriod   600
</VirtualHost>

4.2 Test and Restart Apache

# Test Apache configuration
sudo apache2ctl configtest

# Restart Apache
sudo systemctl restart apache2

Step 5: SSL/TLS Certificate Setup

# Install Certbot
sudo apt install -y certbot python3-certbot-apache

# Obtain SSL certificate
sudo certbot --apache -d yourdomain.com -d www.yourdomain.com

# Test automatic renewal
sudo certbot renew --dry-run

5.2 Configure Auto-renewal

# Add cron job for certificate renewal
sudo crontab -e

# Add this line:
0 12 * * * /usr/bin/certbot renew --quiet

Step 6: Frontend Configuration for Production

6.1 Update Frontend Build Configuration

If you need to rebuild the frontend for production, update the environment:

# In frontend/.env.production
VITE_API_BASE_URL=https://yourdomain.com/api
VITE_WS_URL=wss://yourdomain.com/ws
VITE_MSAL_CLIENT_ID=your-azure-app-client-id
VITE_MSAL_TENANT_ID=your-azure-tenant-id
VITE_MSAL_AUTHORITY=https://login.microsoftonline.com/your-tenant-id
VITE_MSAL_REDIRECT_URI=https://yourdomain.com/auth/callback

6.2 Rebuild and Deploy Frontend (if needed)

# Rebuild frontend
cd frontend
npm run build

# Copy updated files to server
rsync -av dist/ user@your-server:/var/www/html/brief-extractor/

Step 7: Start and Monitor Services

7.1 Start the Backend Service

# Start the service
sudo systemctl start brief-extractor.service

# Check service status
sudo systemctl status brief-extractor.service

# Monitor logs in real-time
sudo journalctl -u brief-extractor.service -f

# Check if service is listening on port 8000
sudo ss -tulpn | grep :8000

7.2 Verify System Health

# Test backend health endpoint
curl -k https://yourdomain.com/health

# Test API endpoint
curl -k https://yourdomain.com/api/config/system

# Check Apache status
sudo systemctl status apache2

# View Apache logs
sudo tail -f /var/log/apache2/brief-extractor_access.log
sudo tail -f /var/log/apache2/brief-extractor_error.log

Step 8: Testing and Validation

8.1 Backend Testing

# Test Python backend directly
cd /var/www/html/brief-extractor/backend
source venv/bin/activate
python -c "
import asyncio
from server.app import create_app
print('Backend imports successful')
"

# Test environment variables
python -c "
import os
from dotenv import load_dotenv
load_dotenv()
print('Environment loaded:', bool(os.getenv('OPENAI_API_KEY')))
"

8.2 Frontend Access Testing

  1. Open browser and navigate to https://yourdomain.com
  2. Check console for any JavaScript errors
  3. Test authentication (login/logout flow)
  4. Upload a test document to verify full workflow
  5. Monitor WebSocket connection in browser developer tools

8.3 End-to-End Testing

  1. Authentication: Verify MSAL login works
  2. File Upload: Test document upload functionality
  3. Processing: Upload a test brief and verify processing
  4. Real-time Updates: Check WebSocket updates during processing
  5. Download Results: Verify CSV download works
  6. Cleanup: Test job deletion

Step 9: Production Monitoring and Maintenance

9.1 Log Monitoring

# Backend application logs
sudo journalctl -u brief-extractor.service -f

# Apache access logs
sudo tail -f /var/log/apache2/brief-extractor_access.log

# Apache error logs
sudo tail -f /var/log/apache2/brief-extractor_error.log

# System logs
sudo tail -f /var/log/syslog

9.2 Resource Monitoring

# Monitor system resources
htop

# Check disk usage
df -h

# Monitor network connections
sudo ss -tulpn | grep -E "(8000|80|443)"

# Check memory usage
free -h

9.3 Automated Cleanup

Create a cleanup script for old files:

sudo nano /usr/local/bin/brief-extractor-cleanup.sh
#!/bin/bash
# Cleanup old uploaded files and results

UPLOAD_DIR="/var/www/html/brief-extractor/backend/server/data/uploads"
OUTPUT_DIR="/var/www/html/brief-extractor/backend/server/data/outputs"

# Remove files older than 24 hours
find "$UPLOAD_DIR" -type f -mtime +1 -delete
find "$OUTPUT_DIR" -type f -mtime +1 -delete

# Log cleanup
echo "$(date): Cleaned up old files" >> /var/log/brief-extractor/cleanup.log
sudo chmod +x /usr/local/bin/brief-extractor-cleanup.sh

# Add to cron
sudo crontab -e
# Add: 0 2 * * * /usr/local/bin/brief-extractor-cleanup.sh

Step 10: Backup and Disaster Recovery

10.1 Backup Strategy

# Create backup script
sudo nano /usr/local/bin/brief-extractor-backup.sh
#!/bin/bash
BACKUP_DIR="/var/backups/brief-extractor"
DATE=$(date +%Y%m%d_%H%M%S)

mkdir -p "$BACKUP_DIR"

# Backup application files
tar -czf "$BACKUP_DIR/app_$DATE.tar.gz" -C /var/www/html brief-extractor

# Backup configuration
cp /etc/systemd/system/brief-extractor.service "$BACKUP_DIR/service_$DATE"
cp /etc/apache2/apache2.conf "$BACKUP_DIR/apache_$DATE.conf"

# Keep only last 7 days of backups
find "$BACKUP_DIR" -name "*.tar.gz" -mtime +7 -delete

echo "$(date): Backup completed" >> /var/log/brief-extractor/backup.log

10.2 Health Checks

# Create health check script
sudo nano /usr/local/bin/brief-extractor-healthcheck.sh
#!/bin/bash
# Health check script

SERVICE_NAME="brief-extractor"
HEALTH_URL="https://yourdomain.com/health"
LOG_FILE="/var/log/brief-extractor/healthcheck.log"

# Check service status
if ! systemctl is-active --quiet $SERVICE_NAME; then
    echo "$(date): Service $SERVICE_NAME is not running" >> $LOG_FILE
    systemctl restart $SERVICE_NAME
fi

# Check HTTP health endpoint
if ! curl -sf $HEALTH_URL > /dev/null; then
    echo "$(date): Health check failed for $HEALTH_URL" >> $LOG_FILE
fi

Troubleshooting Guide

Common Issues and Solutions

  1. Service Won't Start:

    # Check service logs
    sudo journalctl -u brief-extractor.service -n 50
    
    # Check file permissions
    sudo chown -R www-data:www-data /var/www/html/brief-extractor/backend
    
    # Verify Python virtual environment
    cd /var/www/html/brief-extractor/backend
    source venv/bin/activate
    python run_server.py
    
  2. Frontend Not Loading:

    # Check Apache configuration
    sudo apache2ctl configtest
    
    # Verify file permissions
    sudo chown -R www-data:www-data /var/www/html/brief-extractor
    
    # Check SSL certificate
    sudo certbot certificates
    
  3. WebSocket Connection Issues:

    # Check proxy configuration
    # Ensure mod_proxy_wstunnel is enabled
    sudo a2enmod proxy_wstunnel
    sudo systemctl restart apache2
    
  4. Authentication Failures:

    # Verify MSAL configuration
    # Check Azure AD app registration settings
    # Verify redirect URIs match
    
  5. File Upload Issues:

    # Check upload directory permissions
    sudo chmod -R 775 /var/www/html/brief-extractor/backend/server/data/uploads
    
    # Check disk space
    df -h
    

Performance Optimization

  1. Enable Gzip Compression:

    # Add to Apache config
    LoadModule deflate_module modules/mod_deflate.so
    <Location />
        SetOutputFilter DEFLATE
    </Location>
    
  2. Cache Static Assets:

    # Add cache headers for static files
    <LocationMatch "\.(css|js|png|jpg|jpeg|gif|ico|svg)$">
        ExpiresActive On
        ExpiresDefault "access plus 1 month"
    </LocationMatch>
    
  3. Monitor Resource Usage:

    • Install monitoring tools like htop, iotop
    • Set up log rotation to prevent disk space issues
    • Consider upgrading server resources based on usage patterns

Security Considerations

10.1 System Hardening

# Configure firewall
sudo ufw enable
sudo ufw allow 22/tcp   # SSH
sudo ufw allow 80/tcp   # HTTP
sudo ufw allow 443/tcp  # HTTPS

# Disable unused services
sudo systemctl disable apache2-doc

# Regular security updates
sudo apt update && sudo apt upgrade -y

10.2 Application Security

  • API Keys: Ensure all API keys are kept secure and rotated regularly
  • File Validation: The system includes file type validation
  • Authentication: MSAL provides secure authentication for production
  • HTTPS: Always use HTTPS in production
  • CORS: Configure CORS policies for your domain only

Conclusion

After completing these steps, your Enhanced Brief Processing System should be fully deployed and operational on your Ubuntu server. The system will:

  • Serve the React frontend via Apache
  • Proxy API calls to the Python backend
  • Handle WebSocket connections for real-time updates
  • Process documents using multiple AI models
  • Provide secure authentication via Microsoft Azure AD
  • Automatically start on system boot
  • Include monitoring and logging capabilities

Next Steps:

  • Configure monitoring and alerting
  • Set up automated backups
  • Test disaster recovery procedures
  • Monitor costs and usage of AI services
  • Consider scaling strategies for high-volume usage

For ongoing maintenance, monitor the logs regularly and keep the system updated with security patches.