version: '3.8' #============================================================================ # FOXHUNT HFT TRADING SYSTEM - PRODUCTION DOCKER COMPOSE #============================================================================ # High-performance containerized deployment with: # - Trading, ML Training, Backtesting, TLI Services # - HashiCorp Vault (secrets management) # - PostgreSQL (primary database with configuration system) # - Redis (caching and pub/sub) # - InfluxDB (time series data) # - Prometheus & Grafana (monitoring) # - Production-grade security and performance optimizations #============================================================================ services: #========================================================================== # INFRASTRUCTURE SERVICES (Boot First) #========================================================================== vault: image: hashicorp/vault:1.15.0 container_name: foxhunt-vault-prod hostname: foxhunt-vault ports: - "8200:8200" volumes: - vault-data:/vault/data - vault-logs:/vault/logs - ./deployment/vault/config:/vault/config:ro - ./deployment/vault/policies:/vault/policies:ro environment: - VAULT_ADDR=http://0.0.0.0:8200 - VAULT_API_ADDR=http://foxhunt-vault:8200 - VAULT_LOG_LEVEL=INFO - VAULT_DEV_ROOT_TOKEN_ID=${VAULT_ROOT_TOKEN:-foxhunt-dev-root} cap_add: - IPC_LOCK command: > sh -c " vault server -config=/vault/config/vault.hcl & sleep 10 && vault operator init -key-shares=5 -key-threshold=3 > /vault/data/init.txt 2>/dev/null || true && vault operator unseal \$$(grep 'Unseal Key 1:' /vault/data/init.txt | cut -d' ' -f4) 2>/dev/null || true && vault operator unseal \$$(grep 'Unseal Key 2:' /vault/data/init.txt | cut -d' ' -f4) 2>/dev/null || true && vault operator unseal \$$(grep 'Unseal Key 3:' /vault/data/init.txt | cut -d' ' -f4) 2>/dev/null || true && vault auth -method=userpass username=foxhunt password=${VAULT_FOXHUNT_PASSWORD:-foxhunt123} 2>/dev/null || true && wait " networks: - infrastructure-network - backend-network restart: unless-stopped healthcheck: test: ["CMD", "vault", "status"] interval: 30s timeout: 10s retries: 5 start_period: 60s mem_limit: 512m logging: driver: "json-file" options: max-size: "50m" max-file: "5" postgresql: image: postgres:15.4-alpine container_name: foxhunt-postgres-prod hostname: foxhunt-postgres ports: - "5432:5432" volumes: - postgres-data:/var/lib/postgresql/data - ./deployment/postgres/init:/docker-entrypoint-initdb.d:ro - ./deployment/postgres/config/postgresql.conf:/etc/postgresql/postgresql.conf:ro - ./deployment/postgres/config/pg_hba.conf:/etc/postgresql/pg_hba.conf:ro environment: - POSTGRES_DB=foxhunt - POSTGRES_USER=${POSTGRES_USER:-foxhunt} - POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-foxhunt123} - POSTGRES_INITDB_ARGS="--auth-host=md5" - PGUSER=${POSTGRES_USER:-foxhunt} command: > postgres -c config_file=/etc/postgresql/postgresql.conf -c hba_file=/etc/postgresql/pg_hba.conf -c shared_preload_libraries=pg_stat_statements -c max_connections=200 -c shared_buffers=256MB -c effective_cache_size=1GB -c maintenance_work_mem=64MB -c checkpoint_completion_target=0.9 -c wal_buffers=16MB -c default_statistics_target=100 networks: - database-network - backend-network restart: unless-stopped healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-foxhunt} -d foxhunt"] interval: 10s timeout: 5s retries: 5 start_period: 30s mem_limit: 2g logging: driver: "json-file" options: max-size: "100m" max-file: "10" redis: image: redis:7.2-alpine container_name: foxhunt-redis-prod hostname: foxhunt-redis ports: - "6379:6379" volumes: - redis-data:/data - ./deployment/redis/redis.conf:/usr/local/etc/redis/redis.conf:ro command: > redis-server /usr/local/etc/redis/redis.conf --requirepass ${REDIS_PASSWORD:-foxhunt123} --maxmemory 1gb --maxmemory-policy allkeys-lru --save 900 1 --save 300 10 --save 60 10000 networks: - database-network - backend-network restart: unless-stopped healthcheck: test: ["CMD", "redis-cli", "--raw", "incr", "ping"] interval: 10s timeout: 3s retries: 5 start_period: 30s mem_limit: 1g sysctls: - net.core.somaxconn=65535 logging: driver: "json-file" options: max-size: "50m" max-file: "5" influxdb: image: influxdb:2.7-alpine container_name: foxhunt-influxdb-prod hostname: foxhunt-influxdb ports: - "8086:8086" volumes: - influxdb-data:/var/lib/influxdb2 - influxdb-config:/etc/influxdb2 environment: - DOCKER_INFLUXDB_INIT_MODE=setup - DOCKER_INFLUXDB_INIT_USERNAME=${INFLUXDB_USERNAME:-foxhunt} - DOCKER_INFLUXDB_INIT_PASSWORD=${INFLUXDB_PASSWORD:-foxhunt123} - DOCKER_INFLUXDB_INIT_ORG=foxhunt - DOCKER_INFLUXDB_INIT_BUCKET=trading_metrics - DOCKER_INFLUXDB_INIT_RETENTION=30d - DOCKER_INFLUXDB_INIT_ADMIN_TOKEN=${INFLUXDB_TOKEN:-foxhunt-token-12345} networks: - database-network - monitoring-network restart: unless-stopped healthcheck: test: ["CMD", "influx", "ping"] interval: 30s timeout: 10s retries: 5 start_period: 60s mem_limit: 2g logging: driver: "json-file" options: max-size: "100m" max-file: "10" #========================================================================== # CORE TRADING SERVICES #========================================================================== trading-service: build: context: . dockerfile: services/trading_service/Dockerfile args: RUST_VERSION: 1.75.0 BUILD_MODE: release container_name: foxhunt-trading-prod hostname: foxhunt-trading ports: - "8080:8080" # Main service - "9001:9001" # Metrics volumes: - /opt/foxhunt/config:/app/config:ro - /opt/foxhunt/data:/app/data:rw - /var/log/foxhunt:/app/logs:rw - /dev/shm:/dev/shm # Shared memory for HFT IPC - ./certs:/app/certs:ro environment: - RUST_LOG=info,foxhunt=debug - FOXHUNT_ENV=production - DATABASE_URL=postgresql://${POSTGRES_USER:-foxhunt}:${POSTGRES_PASSWORD:-foxhunt123}@foxhunt-postgres:5432/foxhunt - REDIS_URL=redis://:${REDIS_PASSWORD:-foxhunt123}@foxhunt-redis:6379 - INFLUXDB_URL=http://foxhunt-influxdb:8086 - INFLUXDB_TOKEN=${INFLUXDB_TOKEN:-foxhunt-token-12345} - VAULT_ADDR=http://foxhunt-vault:8200 - VAULT_TOKEN=${VAULT_ROOT_TOKEN:-foxhunt-dev-root} depends_on: postgresql: condition: service_healthy redis: condition: service_healthy vault: condition: service_healthy networks: - backend-network - frontend-network # HFT Performance Optimizations cpuset: "2-5" # Dedicated CPU cores cpu_count: 4 mem_limit: 4g memswap_limit: 4g mem_swappiness: 1 oom_kill_disable: true # Real-time capabilities cap_add: - SYS_NICE - IPC_LOCK ulimits: memlock: soft: -1 hard: -1 nofile: soft: 65536 hard: 65536 rtprio: soft: 90 hard: 90 # Network optimizations for HFT sysctls: - net.core.rmem_max=134217728 - net.core.wmem_max=134217728 - net.ipv4.tcp_rmem=4096 65536 134217728 - net.ipv4.tcp_wmem=4096 65536 134217728 - net.core.netdev_max_backlog=5000 restart: unless-stopped healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8080/health"] interval: 10s timeout: 5s retries: 3 start_period: 30s logging: driver: "json-file" options: max-size: "100m" max-file: "10" ml-training-service: build: context: . dockerfile: ./ml/Dockerfile args: RUST_VERSION: 1.75.0 BUILD_MODE: release CUDA_VERSION: "12.1" container_name: foxhunt-ml-training-prod hostname: foxhunt-ml-training ports: - "8082:8082" # Main service - "6006:6006" # TensorBoard - "9002:9002" # Metrics volumes: - /opt/foxhunt/config:/app/config:ro - /opt/foxhunt/models:/app/models:rw - /opt/foxhunt/data:/app/data:ro - /opt/foxhunt/checkpoints:/app/checkpoints:rw - /var/log/foxhunt:/app/logs:rw - /tmp/cuda-cache:/tmp/cuda-cache:rw environment: - RUST_LOG=info,foxhunt_ml=debug - FOXHUNT_ENV=production - DATABASE_URL=postgresql://${POSTGRES_USER:-foxhunt}:${POSTGRES_PASSWORD:-foxhunt123}@foxhunt-postgres:5432/foxhunt - REDIS_URL=redis://:${REDIS_PASSWORD:-foxhunt123}@foxhunt-redis:6379 - TRADING_SERVICE_URL=http://foxhunt-trading:8080 # CUDA/GPU environment - CUDA_VISIBLE_DEVICES=0 - NVIDIA_VISIBLE_DEVICES=0 - NVIDIA_DRIVER_CAPABILITIES=compute,utility - NVIDIA_REQUIRE_CUDA=cuda>=11.8 # ML framework optimizations - OMP_NUM_THREADS=6 - MKL_NUM_THREADS=6 - PYTORCH_CUDA_ALLOC_CONF=max_split_size_mb:512 - TF_GPU_MEMORY_GROWTH=true depends_on: trading-service: condition: service_healthy postgresql: condition: service_healthy networks: - backend-network # GPU-optimized resource allocation cpuset: "8-13" # Dedicated cores for ML mem_limit: 16g memswap_limit: 16g shm_size: 2g # Shared memory for ML frameworks # GPU access (requires nvidia-container-runtime) runtime: nvidia deploy: resources: reservations: devices: - driver: nvidia count: 1 capabilities: [gpu] restart: unless-stopped healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8082/health"] interval: 30s timeout: 15s retries: 5 start_period: 120s logging: driver: "json-file" options: max-size: "100m" max-file: "10" backtesting-service: build: context: . dockerfile: services/backtesting_service/Dockerfile args: RUST_VERSION: 1.75.0 BUILD_MODE: release container_name: foxhunt-backtesting-prod hostname: foxhunt-backtesting ports: - "8083:8083" # Main service - "9003:9003" # Metrics volumes: - /opt/foxhunt/config:/app/config:ro - /opt/foxhunt/data:/app/data:ro - /opt/foxhunt/backtests:/app/backtests:rw - /var/log/foxhunt:/app/logs:rw environment: - RUST_LOG=info,foxhunt_backtesting=debug - FOXHUNT_ENV=production - DATABASE_URL=postgresql://${POSTGRES_USER:-foxhunt}:${POSTGRES_PASSWORD:-foxhunt123}@foxhunt-postgres:5432/foxhunt - REDIS_URL=redis://foxhunt-redis:6379 - ML_SERVICE_URL=http://foxhunt-ml-training:8082 depends_on: trading-service: condition: service_healthy ml-training-service: condition: service_healthy networks: - backend-network cpuset: "14-17" mem_limit: 8g restart: unless-stopped healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8083/health"] interval: 15s timeout: 5s retries: 3 start_period: 60s logging: driver: "json-file" options: max-size: "100m" max-file: "10" tli: build: context: . dockerfile: tli/Dockerfile args: RUST_VERSION: 1.75.0 BUILD_MODE: release container_name: foxhunt-tli-prod hostname: foxhunt-tli ports: - "50051:50051" # gRPC port - "8081:8081" # Web interface - "9004:9004" # Metrics volumes: - /opt/foxhunt/config:/app/config:ro - /var/log/foxhunt:/app/logs:rw environment: - RUST_LOG=info,foxhunt_tli=debug - FOXHUNT_ENV=production - TRADING_SERVICE_URL=http://foxhunt-trading:8080 - ML_SERVICE_URL=http://foxhunt-ml-training:8082 - BACKTESTING_SERVICE_URL=http://foxhunt-backtesting:8083 - GRAFANA_URL=http://foxhunt-grafana:3000 depends_on: trading-service: condition: service_healthy ml-training-service: condition: service_healthy backtesting-service: condition: service_healthy networks: - frontend-network - backend-network cpuset: "18-19" mem_limit: 2g restart: unless-stopped healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8081/health"] interval: 15s timeout: 10s retries: 3 start_period: 45s logging: driver: "json-file" options: max-size: "50m" max-file: "5" #========================================================================== # MONITORING & OBSERVABILITY #========================================================================== prometheus: image: prom/prometheus:v2.47.0 container_name: foxhunt-prometheus-prod hostname: foxhunt-prometheus ports: - "9090:9090" volumes: - prometheus-data:/prometheus - ./deployment/monitoring/prometheus.yml:/etc/prometheus/prometheus.yml:ro - ./deployment/monitoring/rules:/etc/prometheus/rules:ro command: - '--config.file=/etc/prometheus/prometheus.yml' - '--storage.tsdb.path=/prometheus' - '--storage.tsdb.retention.time=30d' - '--storage.tsdb.retention.size=50GB' - '--web.console.libraries=/etc/prometheus/console_libraries' - '--web.console.templates=/etc/prometheus/consoles' - '--web.enable-lifecycle' - '--web.enable-admin-api' - '--query.max-concurrency=50' - '--query.max-samples=50000000' networks: - monitoring-network - backend-network restart: unless-stopped healthcheck: test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:9090/-/healthy"] interval: 30s timeout: 10s retries: 5 start_period: 30s mem_limit: 4g logging: driver: "json-file" options: max-size: "100m" max-file: "5" grafana: image: grafana/grafana:10.1.0 container_name: foxhunt-grafana-prod hostname: foxhunt-grafana ports: - "3000:3000" volumes: - grafana-data:/var/lib/grafana - ./deployment/monitoring/grafana/dashboards:/etc/grafana/provisioning/dashboards:ro - ./deployment/monitoring/grafana/datasources:/etc/grafana/provisioning/datasources:ro - ./deployment/monitoring/grafana/plugins:/var/lib/grafana/plugins environment: - GF_SECURITY_ADMIN_USER=${GRAFANA_ADMIN_USER:-admin} - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_ADMIN_PASSWORD:-admin} - GF_USERS_ALLOW_SIGN_UP=false - GF_SERVER_ROOT_URL=http://localhost:3000 - GF_INSTALL_PLUGINS=grafana-piechart-panel,grafana-worldmap-panel - GF_FEATURE_TOGGLES_ENABLE=ngalert depends_on: prometheus: condition: service_healthy networks: - monitoring-network - frontend-network restart: unless-stopped healthcheck: test: ["CMD-SHELL", "wget --no-verbose --tries=1 --spider http://localhost:3000/api/health || exit 1"] interval: 30s timeout: 10s retries: 5 start_period: 30s mem_limit: 1g logging: driver: "json-file" options: max-size: "50m" max-file: "5" alertmanager: image: prom/alertmanager:v0.26.0 container_name: foxhunt-alertmanager-prod hostname: foxhunt-alertmanager ports: - "9093:9093" volumes: - alertmanager-data:/alertmanager - ./deployment/monitoring/alertmanager.yml:/etc/alertmanager/alertmanager.yml:ro command: - '--config.file=/etc/alertmanager/alertmanager.yml' - '--storage.path=/alertmanager' - '--web.external-url=http://localhost:9093' - '--cluster.advertise-address=0.0.0.0:9093' networks: - monitoring-network restart: unless-stopped healthcheck: test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:9093/-/healthy"] interval: 30s timeout: 10s retries: 5 start_period: 30s mem_limit: 512m logging: driver: "json-file" options: max-size: "50m" max-file: "5" #========================================================================== # REVERSE PROXY & LOAD BALANCING #========================================================================== nginx: image: nginx:1.25-alpine container_name: foxhunt-nginx-prod hostname: foxhunt-nginx ports: - "80:80" - "443:443" volumes: - ./deployment/nginx/nginx.conf:/etc/nginx/nginx.conf:ro - ./deployment/nginx/conf.d:/etc/nginx/conf.d:ro - ./certs:/etc/nginx/certs:ro - nginx-cache:/var/cache/nginx depends_on: - tli - grafana networks: - frontend-network restart: unless-stopped healthcheck: test: ["CMD", "nginx", "-t"] interval: 30s timeout: 10s retries: 5 start_period: 30s mem_limit: 512m logging: driver: "json-file" options: max-size: "100m" max-file: "10" #============================================================================== # NETWORKS (Layered Security Architecture) #============================================================================== networks: frontend-network: driver: bridge driver_opts: com.docker.network.bridge.name: foxhunt-frontend ipam: config: - subnet: 172.20.0.0/24 gateway: 172.20.0.1 backend-network: driver: bridge driver_opts: com.docker.network.bridge.name: foxhunt-backend ipam: config: - subnet: 172.21.0.0/24 gateway: 172.21.0.1 database-network: driver: bridge driver_opts: com.docker.network.bridge.name: foxhunt-database ipam: config: - subnet: 172.22.0.0/24 gateway: 172.22.0.1 infrastructure-network: driver: bridge driver_opts: com.docker.network.bridge.name: foxhunt-infra ipam: config: - subnet: 172.23.0.0/24 gateway: 172.23.0.1 monitoring-network: driver: bridge driver_opts: com.docker.network.bridge.name: foxhunt-monitoring ipam: config: - subnet: 172.24.0.0/24 gateway: 172.24.0.1 #============================================================================== # VOLUMES (Data Persistence) #============================================================================== volumes: # Infrastructure vault-data: driver: local vault-logs: driver: local postgres-data: driver: local redis-data: driver: local influxdb-data: driver: local influxdb-config: driver: local # Monitoring prometheus-data: driver: local grafana-data: driver: local alertmanager-data: driver: local # Application nginx-cache: driver: local