Files
foxhunt/docs/deployment/docker-deployment.md
jgrusewski 7458f1be01 feat(wave12): E2E validation complete - 225-feature pipeline ready
 Validation Results:
- PPO training: 24.2s (1 epoch, 950 samples, dim=225)
- Feature extraction: 105μs/bar (9.5x faster than target)
- Model checkpoint: 293KB (147KB actor + 146KB critic)
- GPU memory: 145MB used (96.4% headroom)
- Zero dimension mismatches

📊 Success Criteria (5/5):
 Feature dimension = 225 (Wave C 201 + Wave D 24)
 Model state_dim = 225
 Training completed without errors
 Checkpoint saved successfully
 No dimension mismatch errors

📁 Training Data Ready:
- ES.FUT: 2.9MB, 180 days
- NQ.FUT: 4.4MB, 180 days
- 6E.FUT: 2.8MB, 180 days
- ZN.FUT: 65KB, 90 days (clean)

🚀 Next: Full production model retraining (4 models, ~10min GPU time)

🤖 Generated with Claude Code (https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-22 22:48:04 +02:00

26 KiB

Docker Deployment Guide

Last Updated: 2025-10-22 Target Environment: Development, Staging, Production Prerequisites: Docker 24.0+, Docker Compose 2.20+ Deployment Time: 15-20 minutes


Table of Contents

  1. Overview
  2. Prerequisites
  3. Pre-Deployment Checklist
  4. Deployment Steps
  5. Service Health Verification
  6. Post-Deployment Validation
  7. Common Issues
  8. Rollback Procedures

Overview

This guide covers deploying the Foxhunt HFT trading system using Docker Compose. The system consists of 9 services:

Core Services

  • API Gateway (Port 50051): Authentication, routing, rate limiting
  • Trading Service (Port 50052): Order execution, position management
  • Backtesting Service (Port 50053): Strategy testing with historical data
  • ML Training Service (Port 50054): Model training and optimization
  • Trading Agent Service (Port 50055): Trading decision orchestration

Infrastructure Services

  • PostgreSQL (Port 5432): TimescaleDB for market data and metrics
  • Redis (Port 6379): Caching and session management
  • Vault (Port 8200): Secrets management
  • Grafana (Port 3000): Monitoring dashboards

Architecture Diagram

graph TB
    subgraph "External Clients"
        TLI[TLI Terminal Client]
        API_CLIENT[API Clients]
    end

    subgraph "API Layer"
        GATEWAY[API Gateway<br/>:50051]
    end

    subgraph "Core Services"
        TRADING[Trading Service<br/>:50052]
        BACKTEST[Backtesting Service<br/>:50053]
        ML_TRAIN[ML Training Service<br/>:50054]
        AGENT[Trading Agent Service<br/>:50055]
    end

    subgraph "Infrastructure"
        POSTGRES[(PostgreSQL<br/>:5432)]
        REDIS[(Redis<br/>:6379)]
        VAULT[Vault<br/>:8200]
        GRAFANA[Grafana<br/>:3000]
    end

    TLI --> GATEWAY
    API_CLIENT --> GATEWAY
    GATEWAY --> TRADING
    GATEWAY --> BACKTEST
    GATEWAY --> ML_TRAIN
    GATEWAY --> AGENT

    TRADING --> POSTGRES
    BACKTEST --> POSTGRES
    ML_TRAIN --> POSTGRES
    AGENT --> POSTGRES

    TRADING --> REDIS
    AGENT --> REDIS

    TRADING --> VAULT
    BACKTEST --> VAULT
    ML_TRAIN --> VAULT
    AGENT --> VAULT

Prerequisites

System Requirements

Minimum (Development):

  • CPU: 4 cores (8 threads recommended)
  • RAM: 16 GB
  • Disk: 50 GB SSD
  • GPU: Optional (CUDA 12.1+ for ML training)

Recommended (Production):

  • CPU: 8 cores (16 threads)
  • RAM: 32 GB
  • Disk: 100 GB NVMe SSD
  • GPU: NVIDIA RTX 3050 Ti or better (4GB+ VRAM)

Software Requirements

# Verify Docker version
docker --version  # Required: 24.0+
# Docker version 24.0.7, build afdd53b

# Verify Docker Compose version
docker-compose --version  # Required: 2.20+
# Docker Compose version v2.20.2

# Check disk space
df -h /var/lib/docker
# Filesystem      Size  Used Avail Use% Mounted on
# /dev/sda1       100G   20G   80G  20% /

# Check available memory
free -h
#               total        used        free      shared  buff/cache   available
# Mem:           31Gi       2.0Gi        25Gi       100Mi       4.0Gi        28Gi

# Optional: Verify GPU availability
nvidia-smi
# +-----------------------------------------------------------------------------+
# | NVIDIA-SMI 525.147.05   Driver Version: 525.147.05   CUDA Version: 12.1     |

Network Requirements

Required Ports (must be available):

  • 50051: API Gateway (gRPC)
  • 50052: Trading Service (gRPC)
  • 50053: Backtesting Service (gRPC)
  • 50054: ML Training Service (gRPC)
  • 50055: Trading Agent Service (gRPC)
  • 5432: PostgreSQL
  • 6379: Redis
  • 8200: Vault
  • 3000: Grafana
  • 9090: Prometheus
  • 8086: InfluxDB

Check port availability:

# Check if ports are already in use
for port in 50051 50052 50053 50054 50055 5432 6379 8200 3000 9090 8086; do
    if lsof -i :$port > /dev/null 2>&1; then
        echo "ERROR: Port $port is already in use"
        lsof -i :$port
    else
        echo "OK: Port $port is available"
    fi
done

Pre-Deployment Checklist

Use this checklist before every deployment:

1. Infrastructure Validation

  • Docker daemon is running: systemctl status docker
  • Docker Compose is installed: docker-compose --version
  • Sufficient disk space (50+ GB): df -h /var/lib/docker
  • Sufficient memory (16+ GB): free -h
  • All required ports are available (see Network Requirements)
  • GPU is detected (if applicable): nvidia-smi

2. Configuration Validation

  • .env file exists in project root
  • Database credentials are set: POSTGRES_PASSWORD
  • Vault token is set: VAULT_TOKEN
  • Redis password is set (if applicable)
  • TLS certificates are present (production only)
  • Backup strategy is configured

3. Code Validation

  • Latest code is pulled: git pull origin main
  • All tests pass: cargo test --workspace
  • Code compiles cleanly: cargo build --release --workspace
  • No pending database migrations: cargo sqlx migrate info
  • Docker images build successfully: docker-compose build

4. Data Validation

  • Market data files are available in test_data/
  • ML models are trained and saved in ml/trained_models/
  • Database backup is recent (< 24 hours old)
  • S3 buckets are accessible (production only)

Deployment Steps

Step 1: Clone Repository and Configure Environment

# Clone repository
cd /opt
sudo git clone https://github.com/your-org/foxhunt.git
cd foxhunt

# Create .env file from template
cp .env.example .env

# Edit .env with production values
nano .env

Required .env Variables:

# Database
POSTGRES_USER=foxhunt
POSTGRES_PASSWORD=<SECURE_PASSWORD>
POSTGRES_DB=foxhunt
DATABASE_URL=postgresql://foxhunt:<SECURE_PASSWORD>@postgres:5432/foxhunt

# Redis
REDIS_URL=redis://redis:6379
REDIS_PASSWORD=<SECURE_PASSWORD>

# Vault
VAULT_ADDR=http://vault:8200
VAULT_TOKEN=<VAULT_ROOT_TOKEN>

# Environment
ENVIRONMENT=production
RUST_LOG=info

# GPU (optional)
CUDA_VISIBLE_DEVICES=0

Step 2: Build Docker Images

# Build all services (5-10 minutes)
docker-compose build --parallel

# Verify images are created
docker images | grep foxhunt
# foxhunt_api_gateway         latest    1.2GB
# foxhunt_trading_service     latest    1.1GB
# foxhunt_backtesting_service latest    1.0GB
# foxhunt_ml_training_service latest    1.5GB
# foxhunt_trading_agent       latest    1.1GB

Build Performance Optimization:

# Use BuildKit for faster builds
export DOCKER_BUILDKIT=1
export COMPOSE_DOCKER_CLI_BUILD=1

# Build with cache from registry (production)
docker-compose build --build-arg BUILDKIT_INLINE_CACHE=1 --pull

Step 3: Initialize Infrastructure Services

Start infrastructure services first (PostgreSQL, Redis, Vault):

# Start infrastructure only
docker-compose up -d postgres redis vault

# Wait for services to be healthy (30-60 seconds)
docker-compose ps
# NAME                COMMAND                  SERVICE             STATUS              PORTS
# foxhunt-postgres-1  "docker-entrypoint.s…"   postgres            Up 30 seconds       0.0.0.0:5432->5432/tcp
# foxhunt-redis-1     "docker-entrypoint.s…"   redis               Up 30 seconds       0.0.0.0:6379->6379/tcp
# foxhunt-vault-1     "docker-entrypoint.s…"   vault               Up 30 seconds       0.0.0.0:8200->8200/tcp

# Verify PostgreSQL is ready
docker-compose exec postgres pg_isready -U foxhunt
# /var/run/postgresql:5432 - accepting connections

# Verify Redis is ready
docker-compose exec redis redis-cli ping
# PONG

Step 4: Apply Database Migrations

# Run migrations (uses sqlx-cli in Docker container)
docker-compose run --rm api_gateway sqlx migrate run

# Verify migrations applied
docker-compose exec postgres psql -U foxhunt -d foxhunt -c "\dt"
#                   List of relations
#  Schema |            Name             | Type  | Owner
# --------+-----------------------------+-------+---------
#  public | _sqlx_migrations            | table | foxhunt
#  public | orders                      | table | foxhunt
#  public | positions                   | table | foxhunt
#  public | regime_states               | table | foxhunt
#  public | regime_transitions          | table | foxhunt
#  public | adaptive_strategy_metrics   | table | foxhunt
# (45 rows)

# Verify migration version
docker-compose exec postgres psql -U foxhunt -d foxhunt -c \
  "SELECT version, description FROM _sqlx_migrations ORDER BY version DESC LIMIT 5;"
#  version |                    description
# ---------+----------------------------------------------------
#  045     | Add regime detection tables
#  044     | Add adaptive strategy metrics
#  043     | Add feature extraction metadata
# (45 rows)

Step 5: Initialize Vault

# Unseal Vault (development mode - auto-unsealed)
# Production: Manually unseal with 3 of 5 keys
docker-compose exec vault vault status
# Sealed: false
# Version: 1.15.2

# Load secrets into Vault
docker-compose exec vault vault kv put secret/foxhunt/database \
  url=postgresql://foxhunt:<PASSWORD>@postgres:5432/foxhunt \
  username=foxhunt \
  password=<PASSWORD>

docker-compose exec vault vault kv put secret/foxhunt/redis \
  url=redis://redis:6379 \
  password=<PASSWORD>

docker-compose exec vault vault kv put secret/foxhunt/jwt \
  secret=<RANDOM_256_BIT_SECRET>

# Verify secrets are stored
docker-compose exec vault vault kv list secret/foxhunt
# Keys
# ----
# database
# jwt
# redis

Step 6: Start Application Services

# Start all application services
docker-compose up -d api_gateway trading_service backtesting_service \
  ml_training_service trading_agent

# Wait for services to be healthy (60-90 seconds)
watch -n 5 'docker-compose ps'

# Verify all services are running
docker-compose ps
# NAME                           STATUS              PORTS
# foxhunt-api_gateway-1          Up 60 seconds       0.0.0.0:50051->50051/tcp
# foxhunt-trading_service-1      Up 60 seconds       0.0.0.0:50052->50052/tcp
# foxhunt-backtesting_service-1  Up 60 seconds       0.0.0.0:50053->50053/tcp
# foxhunt-ml_training_service-1  Up 60 seconds       0.0.0.0:50054->50054/tcp
# foxhunt-trading_agent-1        Up 60 seconds       0.0.0.0:50055->50055/tcp

Step 7: Start Monitoring Services

# Start Grafana and Prometheus
docker-compose up -d grafana prometheus influxdb

# Verify monitoring stack
docker-compose ps grafana prometheus influxdb
# NAME                    STATUS              PORTS
# foxhunt-grafana-1       Up 30 seconds       0.0.0.0:3000->3000/tcp
# foxhunt-prometheus-1    Up 30 seconds       0.0.0.0:9090->9090/tcp
# foxhunt-influxdb-1      Up 30 seconds       0.0.0.0:8086->8086/tcp

Service Health Verification

1. Infrastructure Health Checks

# PostgreSQL health check
docker-compose exec postgres pg_isready -U foxhunt
# Expected: /var/run/postgresql:5432 - accepting connections

# Redis health check
docker-compose exec redis redis-cli ping
# Expected: PONG

# Vault health check
docker-compose exec vault vault status | grep Sealed
# Expected: Sealed: false

2. Application Health Checks

gRPC Health Probes (requires grpc_health_probe):

# Install grpc_health_probe (first time only)
wget -qO /usr/local/bin/grpc_health_probe \
  https://github.com/grpc-ecosystem/grpc-health-probe/releases/download/v0.4.19/grpc_health_probe-linux-amd64
chmod +x /usr/local/bin/grpc_health_probe

# API Gateway health
grpc_health_probe -addr=localhost:50051
# status: SERVING

# Trading Service health
grpc_health_probe -addr=localhost:50052
# status: SERVING

# Backtesting Service health
grpc_health_probe -addr=localhost:50053
# status: SERVING

# ML Training Service health
grpc_health_probe -addr=localhost:50054
# status: SERVING

# Trading Agent Service health
grpc_health_probe -addr=localhost:50055
# status: SERVING

HTTP Health Endpoints:

# API Gateway
curl -f http://localhost:8080/health
# {"status":"healthy","timestamp":"2025-10-22T10:00:00Z","version":"0.1.0"}

# Trading Service
curl -f http://localhost:8081/health
# {"status":"healthy","uptime_seconds":120}

# Backtesting Service
curl -f http://localhost:8082/health
# {"status":"healthy","uptime_seconds":120}

# ML Training Service
curl -f http://localhost:8095/health
# {"status":"healthy","gpu_available":true}

3. Metrics Health Checks

# Verify Prometheus scraping
curl -s http://localhost:9090/api/v1/targets | jq '.data.activeTargets[] | {job: .labels.job, health: .health}'
# Expected output:
# {"job":"api_gateway","health":"up"}
# {"job":"trading_service","health":"up"}
# {"job":"backtesting_service","health":"up"}
# {"job":"ml_training_service","health":"up"}
# {"job":"trading_agent","health":"up"}

# Verify Grafana is accessible
curl -f http://localhost:3000/api/health
# {"database":"ok","version":"10.1.5"}

Post-Deployment Validation

1. Database Connectivity Test

# Test database connection from each service
for service in api_gateway trading_service backtesting_service ml_training_service trading_agent; do
    echo "Testing $service database connection..."
    docker-compose exec $service sh -c \
      'psql $DATABASE_URL -c "SELECT 1 as connection_test;" 2>&1' | grep -q "connection_test"
    if [ $? -eq 0 ]; then
        echo "✓ $service: Database connection OK"
    else
        echo "✗ $service: Database connection FAILED"
    fi
done

2. Redis Connectivity Test

# Test Redis connection
for service in trading_service trading_agent; do
    echo "Testing $service Redis connection..."
    docker-compose exec $service sh -c \
      'redis-cli -u $REDIS_URL ping 2>&1' | grep -q "PONG"
    if [ $? -eq 0 ]; then
        echo "✓ $service: Redis connection OK"
    else
        echo "✗ $service: Redis connection FAILED"
    fi
done

3. Vault Connectivity Test

# Test Vault connection from each service
for service in api_gateway trading_service backtesting_service ml_training_service trading_agent; do
    echo "Testing $service Vault connection..."
    docker-compose exec $service sh -c \
      'vault status 2>&1' | grep -q "Sealed.*false"
    if [ $? -eq 0 ]; then
        echo "✓ $service: Vault connection OK"
    else
        echo "✗ $service: Vault connection FAILED"
    fi
done

4. End-to-End Smoke Test

# Test TLI authentication
tli auth login --username admin --password <PASSWORD>
# Expected: Login successful. Token saved to ~/.foxhunt/token

# Test trading command
tli trade order submit --symbol ES.FUT --action BUY --quantity 1 --order-type MARKET
# Expected: Order submitted successfully. Order ID: <UUID>

# Test backtesting command
tli backtest run --strategy ml --start-date 2025-01-01 --end-date 2025-10-01
# Expected: Backtest started. Job ID: <UUID>

# Test ML prediction
tli trade ml predictions --symbol ES.FUT --limit 1
# Expected: [{symbol: "ES.FUT", prediction: 0.65, confidence: 0.82, timestamp: "..."}]

5. Performance Baseline Test

# Measure API Gateway latency (P50, P95, P99)
for i in {1..1000}; do
    curl -w "@curl-format.txt" -o /dev/null -s http://localhost:8080/health
done | awk '{sum+=$1; sumsq+=($1)^2} END {
    print "P50: " sum/NR " ms"
    print "P95: " (sqrt(sumsq/NR - (sum/NR)^2) * 1.645 + sum/NR) " ms"
    print "P99: " (sqrt(sumsq/NR - (sum/NR)^2) * 2.326 + sum/NR) " ms"
}'
# Expected:
# P50: 0.5 ms
# P95: 2.0 ms
# P99: 5.0 ms

# curl-format.txt:
# %{time_total}

Common Issues

Issue 1: Port Already in Use

Symptom:

Error starting userland proxy: listen tcp4 0.0.0.0:50051: bind: address already in use

Diagnosis:

# Find process using port 50051
lsof -i :50051
# COMMAND   PID     USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
# api_gatew 12345  foxhunt 10u  IPv4 123456      0t0  TCP *:50051 (LISTEN)

Solution:

# Option 1: Stop the conflicting process
kill -9 12345

# Option 2: Change port in docker-compose.yml
# Edit docker-compose.yml and change:
# ports:
#   - "50051:50051"  # Change to "50052:50051"

# Option 3: Stop old containers
docker-compose down
docker-compose up -d

Issue 2: Database Migration Failed

Symptom:

ERROR: relation "orders" already exists

Diagnosis:

# Check migration status
docker-compose exec postgres psql -U foxhunt -d foxhunt -c \
  "SELECT version, success FROM _sqlx_migrations ORDER BY version DESC LIMIT 5;"

Solution:

# Option 1: Rollback failed migration
docker-compose run --rm api_gateway sqlx migrate revert

# Option 2: Reset database (DESTRUCTIVE - development only)
docker-compose down -v
docker-compose up -d postgres
sleep 10
docker-compose run --rm api_gateway sqlx migrate run

# Option 3: Manual fix
docker-compose exec postgres psql -U foxhunt -d foxhunt
# foxhunt=# DROP TABLE IF EXISTS orders CASCADE;
# foxhunt=# \q
docker-compose run --rm api_gateway sqlx migrate run

Issue 3: Vault Sealed

Symptom:

Error reading secret: Error making API request.
Code: 503. Errors: * Vault is sealed

Diagnosis:

docker-compose exec vault vault status
# Sealed: true

Solution:

# Development mode: Restart Vault
docker-compose restart vault

# Production mode: Unseal with keys
docker-compose exec vault vault operator unseal <KEY_1>
docker-compose exec vault vault operator unseal <KEY_2>
docker-compose exec vault vault operator unseal <KEY_3>
# (Requires 3 of 5 unseal keys)

Issue 4: GPU Not Available

Symptom:

CUDA error: no kernel image is available for execution on the device

Diagnosis:

# Check GPU visibility in container
docker-compose exec ml_training_service nvidia-smi
# If "nvidia-smi: command not found": GPU passthrough not configured

# Check NVIDIA runtime
docker info | grep -i runtime
# Runtimes: nvidia runc

Solution:

# Install NVIDIA Container Toolkit
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add -
curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | \
  sudo tee /etc/apt/sources.list.d/nvidia-docker.list
sudo apt-get update && sudo apt-get install -y nvidia-container-toolkit

# Restart Docker daemon
sudo systemctl restart docker

# Update docker-compose.yml to use nvidia runtime
# ml_training_service:
#   runtime: nvidia
#   environment:
#     - NVIDIA_VISIBLE_DEVICES=all

# Restart services
docker-compose down
docker-compose up -d

Issue 5: Out of Memory (OOM)

Symptom:

Container exited with code 137 (OOM killed)

Diagnosis:

# Check container memory usage
docker stats --no-stream
# CONTAINER           CPU %     MEM USAGE / LIMIT     MEM %
# foxhunt-ml_train-1  150%      2.5GiB / 4GiB         62.5%

# Check system memory
free -h
#               total        used        free
# Mem:           16Gi        15Gi       500Mi  # <-- Insufficient free memory

Solution:

# Option 1: Increase Docker memory limit
# Edit /etc/docker/daemon.json:
# {
#   "default-ulimits": {
#     "memlock": {"Name": "memlock", "Hard": -1, "Soft": -1}
#   },
#   "memory": "8g"  # Increase from default
# }
sudo systemctl restart docker

# Option 2: Add memory limits to docker-compose.yml
# ml_training_service:
#   deploy:
#     resources:
#       limits:
#         memory: 8G
#       reservations:
#         memory: 4G

# Option 3: Enable swap (not recommended for production)
sudo swapon -s
sudo fallocate -l 8G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile

Rollback Procedures

See rollback-procedures.md for detailed rollback steps.

Quick Rollback (5 minutes):

# 1. Stop all services
docker-compose down

# 2. Restore database from backup
docker-compose up -d postgres
sleep 10
docker-compose exec postgres psql -U foxhunt -d foxhunt < /backup/foxhunt_backup_2025-10-22.sql

# 3. Checkout previous version
git checkout <PREVIOUS_VERSION_TAG>

# 4. Rebuild and restart
docker-compose build --parallel
docker-compose up -d

# 5. Verify health
grpc_health_probe -addr=localhost:50051

Appendix

A. Docker Compose Configuration

File: docker-compose.yml

version: '3.8'

services:
  # Infrastructure Services
  postgres:
    image: timescale/timescaledb:latest-pg15
    container_name: foxhunt-postgres
    environment:
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      POSTGRES_DB: ${POSTGRES_DB}
    ports:
      - "5432:5432"
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"]
      interval: 10s
      timeout: 5s
      retries: 5
    networks:
      - foxhunt_network

  redis:
    image: redis:7-alpine
    container_name: foxhunt-redis
    command: redis-server --requirepass ${REDIS_PASSWORD}
    ports:
      - "6379:6379"
    volumes:
      - redis_data:/data
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 5
    networks:
      - foxhunt_network

  vault:
    image: vault:1.15
    container_name: foxhunt-vault
    environment:
      VAULT_DEV_ROOT_TOKEN_ID: ${VAULT_TOKEN}
      VAULT_DEV_LISTEN_ADDRESS: 0.0.0.0:8200
    ports:
      - "8200:8200"
    cap_add:
      - IPC_LOCK
    networks:
      - foxhunt_network

  # Application Services
  api_gateway:
    build:
      context: .
      dockerfile: services/api_gateway/Dockerfile
    container_name: foxhunt-api-gateway
    environment:
      DATABASE_URL: ${DATABASE_URL}
      REDIS_URL: ${REDIS_URL}
      VAULT_ADDR: ${VAULT_ADDR}
      VAULT_TOKEN: ${VAULT_TOKEN}
      RUST_LOG: ${RUST_LOG}
    ports:
      - "50051:50051"  # gRPC
      - "8080:8080"    # Health
      - "9091:9091"    # Metrics
    depends_on:
      - postgres
      - redis
      - vault
    networks:
      - foxhunt_network

  trading_service:
    build:
      context: .
      dockerfile: services/trading_service/Dockerfile
    container_name: foxhunt-trading-service
    environment:
      DATABASE_URL: ${DATABASE_URL}
      REDIS_URL: ${REDIS_URL}
      VAULT_ADDR: ${VAULT_ADDR}
      VAULT_TOKEN: ${VAULT_TOKEN}
      RUST_LOG: ${RUST_LOG}
    ports:
      - "50052:50052"  # gRPC
      - "8081:8081"    # Health
      - "9092:9092"    # Metrics
    depends_on:
      - postgres
      - redis
      - vault
    networks:
      - foxhunt_network

  backtesting_service:
    build:
      context: .
      dockerfile: services/backtesting_service/Dockerfile
    container_name: foxhunt-backtesting-service
    environment:
      DATABASE_URL: ${DATABASE_URL}
      VAULT_ADDR: ${VAULT_ADDR}
      VAULT_TOKEN: ${VAULT_TOKEN}
      RUST_LOG: ${RUST_LOG}
    ports:
      - "50053:50053"  # gRPC
      - "8082:8082"    # Health
      - "9093:9093"    # Metrics
    depends_on:
      - postgres
      - vault
    volumes:
      - ./test_data:/app/test_data:ro
    networks:
      - foxhunt_network

  ml_training_service:
    build:
      context: .
      dockerfile: services/ml_training_service/Dockerfile
    container_name: foxhunt-ml-training-service
    runtime: nvidia  # Requires NVIDIA Container Toolkit
    environment:
      DATABASE_URL: ${DATABASE_URL}
      VAULT_ADDR: ${VAULT_ADDR}
      VAULT_TOKEN: ${VAULT_TOKEN}
      RUST_LOG: ${RUST_LOG}
      CUDA_VISIBLE_DEVICES: ${CUDA_VISIBLE_DEVICES}
    ports:
      - "50054:50054"  # gRPC
      - "8095:8095"    # Health
      - "9094:9094"    # Metrics
    depends_on:
      - postgres
      - vault
    volumes:
      - ./test_data:/app/test_data:ro
      - ./ml/trained_models:/app/ml/trained_models
    networks:
      - foxhunt_network

  trading_agent:
    build:
      context: .
      dockerfile: services/trading_agent/Dockerfile
    container_name: foxhunt-trading-agent
    environment:
      DATABASE_URL: ${DATABASE_URL}
      REDIS_URL: ${REDIS_URL}
      VAULT_ADDR: ${VAULT_ADDR}
      VAULT_TOKEN: ${VAULT_TOKEN}
      RUST_LOG: ${RUST_LOG}
    ports:
      - "50055:50055"  # gRPC
      - "8083:8083"    # Health
      - "9095:9095"    # Metrics
    depends_on:
      - postgres
      - redis
      - vault
    networks:
      - foxhunt_network

  # Monitoring Services
  prometheus:
    image: prom/prometheus:latest
    container_name: foxhunt-prometheus
    ports:
      - "9090:9090"
    volumes:
      - ./monitoring/prometheus.yml:/etc/prometheus/prometheus.yml:ro
      - prometheus_data:/prometheus
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--storage.tsdb.path=/prometheus'
      - '--storage.tsdb.retention.time=30d'
    networks:
      - foxhunt_network

  grafana:
    image: grafana/grafana:latest
    container_name: foxhunt-grafana
    environment:
      GF_SECURITY_ADMIN_PASSWORD: ${GRAFANA_PASSWORD}
      GF_USERS_ALLOW_SIGN_UP: "false"
    ports:
      - "3000:3000"
    volumes:
      - grafana_data:/var/lib/grafana
      - ./monitoring/grafana/dashboards:/etc/grafana/provisioning/dashboards:ro
      - ./monitoring/grafana/datasources:/etc/grafana/provisioning/datasources:ro
    depends_on:
      - prometheus
    networks:
      - foxhunt_network

  influxdb:
    image: influxdb:2.7-alpine
    container_name: foxhunt-influxdb
    environment:
      DOCKER_INFLUXDB_INIT_MODE: setup
      DOCKER_INFLUXDB_INIT_USERNAME: ${INFLUXDB_USER}
      DOCKER_INFLUXDB_INIT_PASSWORD: ${INFLUXDB_PASSWORD}
      DOCKER_INFLUXDB_INIT_ORG: foxhunt
      DOCKER_INFLUXDB_INIT_BUCKET: metrics
    ports:
      - "8086:8086"
    volumes:
      - influxdb_data:/var/lib/influxdb2
    networks:
      - foxhunt_network

volumes:
  postgres_data:
  redis_data:
  prometheus_data:
  grafana_data:
  influxdb_data:

networks:
  foxhunt_network:
    driver: bridge

B. Resource Limits Reference

Service CPU Limit Memory Limit GPU Memory
API Gateway 2 cores 512 MB N/A
Trading Service 2 cores 1 GB N/A
Backtesting Service 4 cores 2 GB N/A
ML Training Service 8 cores 8 GB 440 MB
Trading Agent 2 cores 1 GB N/A
PostgreSQL 4 cores 4 GB N/A
Redis 1 core 512 MB N/A

C. Deployment Timeline Reference

Phase Duration Critical Path
Pre-deployment checks 5 min Yes
Build Docker images 10 min Yes
Start infrastructure 2 min Yes
Apply migrations 1 min Yes
Start app services 3 min Yes
Health verification 2 min Yes
Post-deployment validation 5 min No
Total 15-20 min -

End of Docker Deployment Guide