✅ 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>
1041 lines
26 KiB
Markdown
1041 lines
26 KiB
Markdown
# 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](#overview)
|
|
2. [Prerequisites](#prerequisites)
|
|
3. [Pre-Deployment Checklist](#pre-deployment-checklist)
|
|
4. [Deployment Steps](#deployment-steps)
|
|
5. [Service Health Verification](#service-health-verification)
|
|
6. [Post-Deployment Validation](#post-deployment-validation)
|
|
7. [Common Issues](#common-issues)
|
|
8. [Rollback Procedures](#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
|
|
|
|
```mermaid
|
|
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
|
|
|
|
```bash
|
|
# 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**:
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
# 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**:
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
# 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**:
|
|
```bash
|
|
# 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):
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
# 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`):
|
|
|
|
```bash
|
|
# 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**:
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
# 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**:
|
|
```bash
|
|
# 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**:
|
|
```bash
|
|
# 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**:
|
|
```bash
|
|
# 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**:
|
|
```bash
|
|
# 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**:
|
|
```bash
|
|
docker-compose exec vault vault status
|
|
# Sealed: true
|
|
```
|
|
|
|
**Solution**:
|
|
```bash
|
|
# 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**:
|
|
```bash
|
|
# 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**:
|
|
```bash
|
|
# 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**:
|
|
```bash
|
|
# 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**:
|
|
```bash
|
|
# 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](rollback-procedures.md) for detailed rollback steps.
|
|
|
|
**Quick Rollback** (5 minutes):
|
|
|
|
```bash
|
|
# 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`
|
|
|
|
```yaml
|
|
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**
|