Deployment Guide

Production Deployment Overview

This guide covers deploying the RACE Management Console in production environments with proper security, scalability, and reliability configurations.

Prerequisites
System Requirements
  • Operating System: Linux (Ubuntu 20.04+ recommended)
  • Python: 3.9+ with pip
  • Database: PostgreSQL 12+ for production
  • Memory: 4GB RAM minimum, 8GB recommended
  • Storage: 50GB minimum for logs and data
  • Network: HTTPS access to AVEVA CONNECT services
External Dependencies
  • AVEVA CONNECT: Data Services access credentials
  • SSL Certificate: For HTTPS deployment
  • Reverse Proxy: Nginx/Apache for production
  • Process Manager: systemd for service management
  • Monitoring: Log aggregation and alerting
  • Backup: Database backup solution
Environment Setup
1. System User and Directories
# Create system user
sudo useradd -r -s /bin/false race-app
sudo mkdir -p /opt/race-console
sudo mkdir -p /var/log/race-console
sudo chown race-app:race-app /opt/race-console /var/log/race-console

# Create application directory structure
cd /opt/race-console
sudo -u race-app mkdir -p {config,logs,static,templates}
2. Python Environment
# Install Python dependencies
sudo apt update
sudo apt install python3-pip python3-venv postgresql-client

# Create virtual environment
sudo -u race-app python3 -m venv /opt/race-console/venv
sudo -u race-app /opt/race-console/venv/bin/pip install --upgrade pip

# Install application dependencies
sudo -u race-app /opt/race-console/venv/bin/pip install -r requirements.txt
3. Database Setup
# PostgreSQL installation and configuration
sudo apt install postgresql postgresql-contrib

# Create database and user
sudo -u postgres createdb race_console_prod
sudo -u postgres createuser race_app
sudo -u postgres psql -c "ALTER USER race_app WITH PASSWORD 'your_secure_password';"
sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE race_console_prod TO race_app;"

# Initialize database schema
export DATABASE_URL="postgresql://race_app:your_secure_password@localhost/race_console_prod"
/opt/race-console/venv/bin/python -c "from app import db; db.create_all()"
Production Configuration
Environment Variables

Create /opt/race-console/.env with production settings:

# Database Configuration
DATABASE_URL=postgresql://race_app:your_secure_password@localhost/race_console_prod

# Security Settings
SESSION_SECRET=your_very_long_random_secret_key_here
FLASK_ENV=production
SECRET_KEY=another_very_long_random_secret_key

# AVEVA CONNECT Configuration (optional defaults)
CONNECT_TENANT_ID=your_tenant_id
CONNECT_NAMESPACE_ID=your_namespace_id
CONNECT_CLIENT_ID=your_client_id
CONNECT_CLIENT_SECRET=your_client_secret

# Logging Configuration
LOG_LEVEL=INFO
LOG_FILE=/var/log/race-console/app.log

# Performance Settings
WORKERS=4
WORKER_CONNECTIONS=1000
TIMEOUT=30
Application Configuration

Update /opt/race-console/config/app_config.json:

{
  "monitoring": {
    "poll_interval": 30,
    "batch_size": 100,
    "timeout": 10,
    "retry_attempts": 3
  },
  "events": {
    "max_age_days": 90,
    "cleanup_interval_hours": 24,
    "batch_cleanup_size": 1000
  },
  "security": {
    "session_timeout": 3600,
    "max_login_attempts": 5,
    "lockout_duration": 300
  },
  "performance": {
    "cache_timeout": 300,
    "max_concurrent_requests": 50,
    "database_pool_size": 20
  }
}
Service Configuration
Systemd Service File

Create /etc/systemd/system/race-console.service:

[Unit]
Description=RACE Management Console
After=network.target postgresql.service
Requires=postgresql.service

[Service]
Type=exec
User=race-app
Group=race-app
WorkingDirectory=/opt/race-console
Environment=PATH=/opt/race-console/venv/bin
EnvironmentFile=/opt/race-console/.env
ExecStart=/opt/race-console/venv/bin/gunicorn --bind 0.0.0.0:5000 --workers 4 --timeout 30 --keep-alive 2 --max-requests 1000 --max-requests-jitter 100 main:app
ExecReload=/bin/kill -s HUP $MAINPID
Restart=always
RestartSec=10

# Security settings
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/opt/race-console /var/log/race-console

[Install]
WantedBy=multi-user.target
Service Management
# Enable and start the service
sudo systemctl daemon-reload
sudo systemctl enable race-console.service
sudo systemctl start race-console.service

# Check service status
sudo systemctl status race-console.service

# View logs
sudo journalctl -u race-console.service -f
Reverse Proxy (Nginx)
Nginx Configuration

Create /etc/nginx/sites-available/race-console:

server {
    listen 80;
    server_name race-console.your-domain.com;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name race-console.your-domain.com;

    # SSL Configuration
    ssl_certificate /etc/ssl/certs/race-console.crt;
    ssl_certificate_key /etc/ssl/private/race-console.key;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512;
    ssl_prefer_server_ciphers off;

    # Security headers
    add_header X-Frame-Options DENY;
    add_header X-Content-Type-Options nosniff;
    add_header X-XSS-Protection "1; mode=block";
    add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";

    # Proxy settings
    location / {
        proxy_pass http://127.0.0.1:5000;
        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_redirect off;
        
        # WebSocket support (if needed)
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }

    # Static files
    location /static {
        alias /opt/race-console/static;
        expires 1y;
        add_header Cache-Control "public, immutable";
    }

    # Logging
    access_log /var/log/nginx/race-console.access.log;
    error_log /var/log/nginx/race-console.error.log;
}
Enable Site
# Enable the site
sudo ln -s /etc/nginx/sites-available/race-console /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
Security Configuration
Firewall Configuration
# UFW firewall rules
sudo ufw enable
sudo ufw allow ssh
sudo ufw allow 'Nginx Full'
sudo ufw deny 5000  # Block direct access to app

# PostgreSQL (if external)
sudo ufw allow from your_db_server_ip to any port 5432
File Permissions
# Set proper file permissions
sudo chmod 750 /opt/race-console
sudo chmod 640 /opt/race-console/.env
sudo chmod 755 /opt/race-console/static
sudo chmod 644 /opt/race-console/config/*
Database Security
  • Use strong passwords for database users
  • Enable SSL connections to PostgreSQL
  • Restrict database access by IP
  • Regular security updates
  • Monitor failed login attempts
  • Enable query logging for audit
Application Security
  • Use environment variables for secrets
  • Enable CSRF protection
  • Implement rate limiting
  • Regular dependency updates
  • Monitor application logs
  • Implement backup encryption
Monitoring & Maintenance
Log Management
# Logrotate configuration
# /etc/logrotate.d/race-console
/var/log/race-console/*.log {
    daily
    missingok
    rotate 30
    compress
    delaycompress
    notifempty
    copytruncate
    postrotate
        systemctl reload race-console
    endscript
}
Health Check Script
#!/bin/bash
# /opt/race-console/scripts/health-check.sh

# Check service status
if ! systemctl is-active --quiet race-console; then
    echo "CRITICAL: RACE Console service is down"
    exit 2
fi

# Check HTTP response
if ! curl -f -s http://localhost:5000/ > /dev/null; then
    echo "CRITICAL: HTTP endpoint not responding"
    exit 2
fi

echo "OK: RACE Console is healthy"
exit 0
Backup Strategy
#!/bin/bash
# /opt/race-console/scripts/backup.sh

DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_DIR="/backup/race-console"

# Database backup
pg_dump -h localhost -U race_app race_console_prod > \
    "$BACKUP_DIR/database_$DATE.sql"

# Configuration backup
tar -czf "$BACKUP_DIR/config_$DATE.tar.gz" \
    /opt/race-console/config \
    /opt/race-console/.env

# Cleanup old backups (keep 30 days)
find "$BACKUP_DIR" -name "*.sql" -mtime +30 -delete
find "$BACKUP_DIR" -name "*.tar.gz" -mtime +30 -delete
Monitoring Checklist
  • Service availability monitoring
  • Database connection health
  • AVEVA CONNECT API connectivity
  • Disk space and memory usage
  • Application error rates
  • Response time monitoring
Scaling Considerations
Horizontal Scaling
  • Load Balancer: Distribute traffic across multiple instances
  • Session Storage: Use Redis for shared session storage
  • Database: Read replicas for improved performance
  • Static Files: CDN for static asset delivery
  • Monitoring: Centralized logging and metrics
Performance Optimization
  • Database query optimization
  • Connection pooling configuration
  • Caching strategies (Redis/Memcached)
  • Background task optimization
  • Asset minification and compression
High Availability
  • Database HA: PostgreSQL streaming replication
  • Application HA: Multiple server instances
  • Load Balancing: Health check integration
  • Failover: Automated failover procedures
  • Backup: Cross-region backup replication
Container Deployment

For containerized deployments:

  • Docker containerization
  • Kubernetes orchestration
  • Persistent volume management
  • Service mesh integration
  • Auto-scaling policies