Files
foxhunt/docker-compose.yml
jgrusewski 69d435cb52 feat(trading): integrate QuestDB metrics provider for feedback loop
Replace stub metrics provider with real QuestDBMetricsProvider that
queries QuestDB via PostgreSQL wire protocol (port 8812) for rolling
model Sharpe, win rates, confidence buckets, and ensemble metrics.

- Add QuestDB service to docker-compose.yml (8.2.3, ports 9009/8812/9003)
- Create questdb_metrics.rs with 5 SQL queries and graceful fallback
- Wire QuestDBMetricsProvider into main.rs (replaces StubMetricsProvider)
- Fix unused Instant import in feedback_loop.rs (#[cfg(test)] scope)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 13:57:46 +01:00

513 lines
17 KiB
YAML

version: '3.8'
services:
# PostgreSQL - Primary database for SQLx compilation and app data
postgres:
image: timescale/timescaledb:latest-pg16
container_name: foxhunt-postgres
environment:
POSTGRES_DB: foxhunt
POSTGRES_USER: foxhunt
POSTGRES_PASSWORD: foxhunt_dev_password
ports:
- "5432:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U foxhunt"]
interval: 10s
timeout: 5s
retries: 5
networks:
- foxhunt-network
# Redis - Caching and real-time data
redis:
image: redis:7-alpine
container_name: foxhunt-redis
command: >
redis-server
--maxmemory 2gb
--maxmemory-policy allkeys-lru
ports:
- "6379:6379"
volumes:
- redis_data:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
networks:
- foxhunt-network
# QuestDB - High-performance time-series DB for ML metrics and feedback loop
questdb:
image: questdb/questdb:8.2.3
container_name: foxhunt-questdb
ports:
- "9009:9009" # ILP ingestion (Influx Line Protocol)
- "8812:8812" # PostgreSQL wire protocol (SQL queries)
- "9003:9003" # HTTP REST API + Web Console
volumes:
- questdb_data:/var/lib/questdb
environment:
- QDB_PG_ENABLED=true
- QDB_LINE_TCP_NET_BIND_TO=0.0.0.0:9009
healthcheck:
test: ["CMD-SHELL", "wget --no-verbose --tries=1 -O /dev/null http://localhost:9003/exec?query=SELECT%201 || exit 1"]
interval: 10s
timeout: 5s
retries: 5
networks:
- foxhunt-network
# InfluxDB - Time-series data for HFT metrics
influxdb:
image: influxdb:2.7-alpine
container_name: foxhunt-influxdb
environment:
DOCKER_INFLUXDB_INIT_MODE: setup
DOCKER_INFLUXDB_INIT_USERNAME: foxhunt
DOCKER_INFLUXDB_INIT_PASSWORD: foxhunt_dev_password
DOCKER_INFLUXDB_INIT_ORG: foxhunt
DOCKER_INFLUXDB_INIT_BUCKET: trading_metrics
DOCKER_INFLUXDB_INIT_RETENTION: 30d
ports:
- "8086:8086"
volumes:
- influxdb_data:/var/lib/influxdb2
healthcheck:
test: ["CMD", "influx", "ping"]
interval: 30s
timeout: 10s
retries: 5
networks:
- foxhunt-network
# HashiCorp Vault - Secrets management
vault:
image: hashicorp/vault:1.15
container_name: foxhunt-vault
environment:
VAULT_ADDR: http://0.0.0.0:8200
VAULT_DEV_ROOT_TOKEN_ID: foxhunt-dev-root
ports:
- "8200:8200"
volumes:
- vault_data:/vault/data
cap_add:
- IPC_LOCK
command: vault server -dev -dev-listen-address=0.0.0.0:8200
healthcheck:
test: ["CMD", "vault", "status"]
interval: 30s
timeout: 10s
retries: 5
networks:
- foxhunt-network
# Prometheus - HFT Metrics Collection
prometheus:
image: prom/prometheus:latest
container_name: foxhunt-prometheus
ports:
- "9090:9090"
volumes:
- prometheus_data:/prometheus
- ./config/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro
- ./config/prometheus/rules:/etc/prometheus/rules:ro
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--storage.tsdb.retention.time=15d'
- '--web.enable-lifecycle'
- '--query.max-concurrency=50'
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:9090/-/healthy"]
interval: 30s
timeout: 10s
retries: 5
networks:
- foxhunt-network
# Grafana - HFT Trading Dashboards
grafana:
image: grafana/grafana:latest
container_name: foxhunt-grafana
ports:
- "3000:3000"
volumes:
- grafana_data:/var/lib/grafana
- ./config/grafana/dashboards:/var/lib/grafana/dashboards:ro
- ./config/grafana/provisioning:/etc/grafana/provisioning:ro
environment:
- GF_SECURITY_ADMIN_PASSWORD=foxhunt123
- GF_USERS_ALLOW_SIGN_UP=false
- GF_DASHBOARDS_DEFAULT_HOME_DASHBOARD_PATH=/var/lib/grafana/dashboards/hft-trading-performance.json
depends_on:
prometheus:
condition: service_healthy
healthcheck:
test: ["CMD-SHELL", "wget --no-verbose --tries=1 --spider http://localhost:3000/api/health || exit 1"]
interval: 30s
timeout: 10s
retries: 5
networks:
- foxhunt-network
# MinIO - S3-compatible object storage for model checkpoints and training data
minio:
image: minio/minio:latest
container_name: foxhunt-minio
ports:
- "9000:9000" # API endpoint
- "9001:9001" # Console UI
environment:
MINIO_ROOT_USER: foxhunt
MINIO_ROOT_PASSWORD: foxhunt_dev_password
MINIO_REGION_NAME: us-east-1
command: server /data --console-address ":9001"
volumes:
- minio_data:/data
healthcheck:
test: ["CMD", "mc", "ready", "local"]
interval: 10s
timeout: 5s
retries: 5
networks:
- foxhunt-network
# =========================================================================
# Application Services (gRPC microservices)
# =========================================================================
# Trading Service - Core trading logic (port 50052)
trading_service:
build:
context: .
dockerfile: services/trading_service/Dockerfile
container_name: foxhunt-trading-service
env_file:
- .env # Load JWT_SECRET and other config from .env (Wave 147)
ports:
- "50052:50051" # Map external 50052 to internal 50051
- "9092:9092" # Metrics
environment:
- DATABASE_URL=postgresql://foxhunt:foxhunt_dev_password@postgres:5432/foxhunt
- REDIS_URL=redis://redis:6379
- VAULT_ADDR=http://vault:8200
- VAULT_TOKEN=foxhunt-dev-root
- JWT_SECRET=${JWT_SECRET:-dev_secret_key_change_in_production}
- JWT_ISSUER=foxhunt-api-gateway
- JWT_AUDIENCE=foxhunt-services
# TLS Configuration - Wave H1 mTLS implementation
- TLS_ENABLED=${TLS_ENABLED:-false}
- TLS_PROTOCOL_VERSION=${TLS_PROTOCOL_VERSION:-TLS13}
- TLS_REQUIRE_CLIENT_CERT=${TLS_REQUIRE_CLIENT_CERT:-true}
- TLS_CERT_PATH=/tmp/foxhunt/certs/server-cert.pem
- TLS_KEY_PATH=/tmp/foxhunt/certs/server-key.pem
- TLS_CA_PATH=/tmp/foxhunt/certs/ca/ca-cert.pem
# mTLS Validation Options
- MTLS_ENABLE_REVOCATION_CHECK=${MTLS_ENABLE_REVOCATION_CHECK:-false}
- MTLS_CRL_URL=${MTLS_CRL_URL:-}
# QuestDB for ML feedback loop metrics
- QUESTDB_ILP_HOST=questdb:9009
- QUESTDB_PG_URL=postgresql://admin:quest@questdb:8812/qdb
- KILL_SWITCH_SOCKET_PATH=/tmp/kill_switch.sock
- GRPC_PORT=50051
- RUST_LOG=info
- RUST_BACKTRACE=1
volumes:
- ./certs:/tmp/foxhunt/certs:ro
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
vault:
condition: service_healthy
healthcheck:
test: ["CMD", "/usr/local/bin/grpc_health_probe", "-addr=localhost:50051"]
interval: 10s
timeout: 5s
start_period: 30s
retries: 3
networks:
- foxhunt-network
restart: unless-stopped
# Backtesting Service - Strategy testing (port 50053)
backtesting_service:
build:
context: .
dockerfile: services/backtesting_service/Dockerfile
container_name: foxhunt-backtesting-service
env_file:
- .env # Load JWT_SECRET and other config from .env (Wave 147)
ports:
- "50053:50053" # Map external 50053 to internal 50053
- "9093:9093" # Metrics
- "8083:8082" # Health check endpoint
environment:
- DATABASE_URL=postgresql://foxhunt:foxhunt_dev_password@postgres:5432/foxhunt
- REDIS_URL=redis://redis:6379
- VAULT_ADDR=http://vault:8200
- VAULT_TOKEN=foxhunt-dev-root
- JWT_SECRET=${JWT_SECRET:-dev_secret_key_change_in_production}
- JWT_ISSUER=foxhunt-api-gateway
- JWT_AUDIENCE=foxhunt-services
- BENZINGA_API_KEY=${BENZINGA_API_KEY:-demo_key_please_replace}
# DBN Data Configuration - Wave 153 Real Data Integration
- USE_DBN_DATA=${USE_DBN_DATA:-false}
- DBN_SYMBOL_MAPPINGS=${DBN_SYMBOL_MAPPINGS:-ES.FUT:/workspace/test_data/real/databento/ES.FUT_ohlcv-1m_2024-01-02.dbn}
- DBN_SYMBOL_MAP=${DBN_SYMBOL_MAP:-BTC/USD:ES.FUT,ETH/USD:ES.FUT}
# TLS Configuration - Wave H1 mTLS implementation (updated)
- TLS_ENABLED=${TLS_ENABLED:-false}
- TLS_PROTOCOL_VERSION=${TLS_PROTOCOL_VERSION:-TLS13}
- TLS_REQUIRE_CLIENT_CERT=${TLS_REQUIRE_CLIENT_CERT:-true}
- TLS_CERT_PATH=/tmp/foxhunt/certs/server-cert.pem
- TLS_KEY_PATH=/tmp/foxhunt/certs/server-key.pem
- TLS_CA_PATH=/tmp/foxhunt/certs/ca/ca-cert.pem
# mTLS Validation Options
- MTLS_ENABLE_REVOCATION_CHECK=${MTLS_ENABLE_REVOCATION_CHECK:-false}
- MTLS_CRL_URL=${MTLS_CRL_URL:-}
- RUST_LOG=info
- RUST_BACKTRACE=1
volumes:
- ./certs:/tmp/foxhunt/certs:ro
- ./test_data:/workspace/test_data:ro
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
vault:
condition: service_healthy
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8082/health"]
interval: 10s
timeout: 5s
start_period: 30s
retries: 3
networks:
- foxhunt-network
restart: unless-stopped
# ML Training Service - Model training with GPU acceleration (port 50054)
ml_training_service:
build:
context: .
dockerfile: services/ml_training_service/Dockerfile
container_name: foxhunt-ml-training-service
runtime: nvidia
env_file:
- .env # Load JWT_SECRET and other config from .env (Wave 147)
ports:
- "50054:50053" # Map external 50054 to internal 50053
- "9094:9094" # Metrics
- "8095:8080" # Health endpoint (unique host port)
environment:
- DATABASE_URL=postgresql://foxhunt:foxhunt_dev_password@postgres:5432/foxhunt
- REDIS_URL=redis://redis:6379
- VAULT_ADDR=http://vault:8200
- VAULT_TOKEN=foxhunt-dev-root
- JWT_SECRET=${JWT_SECRET:-dev_secret_key_change_in_production}
- JWT_ISSUER=foxhunt-api-gateway
- JWT_AUDIENCE=foxhunt-services
# GPU Configuration
- NVIDIA_VISIBLE_DEVICES=all
- NVIDIA_DRIVER_CAPABILITIES=compute,utility
- CUDA_VISIBLE_DEVICES=0
# MinIO Configuration for Model Storage
- S3_ENDPOINT=http://minio:9000
- S3_ACCESS_KEY=foxhunt
- S3_SECRET_KEY=foxhunt_dev_password
- S3_BUCKET=ml-models
- S3_REGION=us-east-1
# Hyperparameter Tuning Configuration
- OPTUNA_STORAGE=postgresql://foxhunt:foxhunt_dev_password@postgres:5432/foxhunt
- OPTUNA_STUDY_NAME=${OPTUNA_STUDY_NAME:-foxhunt-hpt}
- OPTUNA_N_TRIALS=${OPTUNA_N_TRIALS:-100}
# TLS Configuration - Wave H1 mTLS implementation (updated)
- TLS_ENABLED=${TLS_ENABLED:-false}
- TLS_PROTOCOL_VERSION=${TLS_PROTOCOL_VERSION:-TLS13}
- TLS_REQUIRE_CLIENT_CERT=${TLS_REQUIRE_CLIENT_CERT:-true}
- TLS_CERT_PATH=/tmp/foxhunt/certs/server-cert.pem
- TLS_KEY_PATH=/tmp/foxhunt/certs/server-key.pem
- TLS_CA_PATH=/tmp/foxhunt/certs/ca/ca-cert.pem
# mTLS Validation Options
- MTLS_ENABLE_REVOCATION_CHECK=${MTLS_ENABLE_REVOCATION_CHECK:-false}
- MTLS_CRL_URL=${MTLS_CRL_URL:-}
# Logging
- RUST_LOG=info
- RUST_BACKTRACE=1
volumes:
- ./certs:/tmp/foxhunt/certs:ro
- ./models:/tmp/foxhunt/models
- ./checkpoints:/tmp/foxhunt/checkpoints
# Training data mounts
- ./test_data/real/databento/ml_training:/data/training:ro
- ./tuning_config.yaml:/app/tuning_config.yaml:ro
- ./optuna_studies:/app/optuna_studies
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: 1
capabilities: [gpu]
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
vault:
condition: service_healthy
minio:
condition: service_healthy
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
interval: 10s
timeout: 5s
start_period: 30s
retries: 3
networks:
- foxhunt-network
restart: unless-stopped
# Trading Agent Service - Portfolio management (port 50055)
trading_agent_service:
build:
context: .
dockerfile: services/trading_agent_service/Dockerfile
container_name: foxhunt-trading-agent-service
env_file:
- .env
ports:
- "50055:50055" # gRPC
- "8084:8083" # Health (external 8084 -> internal 8083)
- "9095:9095" # Metrics
environment:
- DATABASE_URL=postgresql://foxhunt:foxhunt_dev_password@postgres:5432/foxhunt
- REDIS_URL=redis://redis:6379
- VAULT_ADDR=http://vault:8200
- VAULT_TOKEN=foxhunt-dev-root
- JWT_SECRET=${JWT_SECRET:-dev_secret_key_change_in_production}
# TLS Configuration - Wave H1 mTLS implementation
- TLS_ENABLED=${TLS_ENABLED:-false}
- TLS_PROTOCOL_VERSION=${TLS_PROTOCOL_VERSION:-TLS13}
- TLS_REQUIRE_CLIENT_CERT=${TLS_REQUIRE_CLIENT_CERT:-true}
- TLS_CERT_PATH=/tmp/foxhunt/certs/server-cert.pem
- TLS_KEY_PATH=/tmp/foxhunt/certs/server-key.pem
- TLS_CA_PATH=/tmp/foxhunt/certs/ca/ca-cert.pem
# mTLS Validation Options
- MTLS_ENABLE_REVOCATION_CHECK=${MTLS_ENABLE_REVOCATION_CHECK:-false}
- MTLS_CRL_URL=${MTLS_CRL_URL:-}
- RUST_LOG=info
- RUST_BACKTRACE=1
volumes:
- ./certs:/tmp/foxhunt/certs:ro
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
vault:
condition: service_healthy
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8083/health"]
interval: 10s
timeout: 5s
start_period: 30s
retries: 3
networks:
- foxhunt-network
restart: unless-stopped
# API Gateway - Auth + routing (port 50051)
api_gateway:
build:
context: .
dockerfile: services/api_gateway/Dockerfile
container_name: foxhunt-api-gateway
env_file:
- .env # Load JWT_SECRET and other config from .env (Wave 147)
ports:
- "50051:50050" # Map external 50051 to internal 50050
- "9091:9091" # Metrics
environment:
- GATEWAY_BIND_ADDR=0.0.0.0:50050
- DATABASE_URL=postgresql://foxhunt:foxhunt_dev_password@postgres:5432/foxhunt
- REDIS_URL=redis://redis:6379
- VAULT_ADDR=http://vault:8200
- VAULT_TOKEN=foxhunt-dev-root
- TRADING_SERVICE_URL=http://trading_service:50051
- BACKTESTING_SERVICE_URL=https://backtesting_service:50053
- ML_TRAINING_SERVICE_URL=https://ml_training_service:50053
- JWT_SECRET=${JWT_SECRET:-dev_secret_key_change_in_production}
- JWT_ISSUER=foxhunt-api-gateway
- JWT_AUDIENCE=foxhunt-services
# TLS Certificate Configuration for Backtesting Service (mTLS)
# Using dev CA-signed certificates (matching Backtesting Service CA)
- BACKTESTING_TLS_CA_CERT=/tmp/foxhunt/certs/ca/ca-cert.pem
- BACKTESTING_TLS_CLIENT_CERT=/tmp/foxhunt/certs/client-cert.pem
- BACKTESTING_TLS_CLIENT_KEY=/tmp/foxhunt/certs/client-key.pem
# TLS Certificate Configuration for ML Training Service (mTLS)
# Using dev CA-signed certificates (matching ML Training Service CA)
- ML_TRAINING_TLS_CA_CERT=/tmp/foxhunt/certs/ca/ca-cert.pem
- ML_TRAINING_TLS_CLIENT_CERT=/tmp/foxhunt/certs/client-cert.pem
- ML_TRAINING_TLS_CLIENT_KEY=/tmp/foxhunt/certs/client-key.pem
# TLS Server Configuration - Wave H1 mTLS implementation
- TLS_ENABLED=${TLS_ENABLED:-false}
- TLS_PROTOCOL_VERSION=${TLS_PROTOCOL_VERSION:-TLS13}
- TLS_REQUIRE_CLIENT_CERT=${TLS_REQUIRE_CLIENT_CERT:-true}
- TLS_CERT_PATH=/tmp/foxhunt/certs/server-cert.pem
- TLS_KEY_PATH=/tmp/foxhunt/certs/server-key.pem
- TLS_CA_PATH=/tmp/foxhunt/certs/ca/ca-cert.pem
# mTLS Validation Options
- MTLS_ENABLE_REVOCATION_CHECK=${MTLS_ENABLE_REVOCATION_CHECK:-false}
- MTLS_CRL_URL=${MTLS_CRL_URL:-}
# Service Configuration
- RATE_LIMIT_RPS=100
- ENABLE_AUDIT_LOGGING=true
- RUST_LOG=info
- RUST_BACKTRACE=1
volumes:
- ./certs:/tmp/foxhunt/certs:ro
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
vault:
condition: service_healthy
trading_service:
condition: service_healthy
backtesting_service:
condition: service_healthy
ml_training_service:
condition: service_healthy
healthcheck:
test: ["CMD", "/usr/local/bin/grpc_health_probe", "-addr=localhost:50050"]
interval: 10s
timeout: 5s
start_period: 30s
retries: 3
networks:
- foxhunt-network
restart: unless-stopped
volumes:
postgres_data:
redis_data:
questdb_data:
influxdb_data:
vault_data:
prometheus_data:
grafana_data:
minio_data:
networks:
foxhunt-network:
driver: bridge