version: '3.8' #============================================================================ # FOXHUNT HFT INFRASTRUCTURE-ONLY DEPLOYMENT #============================================================================ # Independent infrastructure services for development/testing: # - HashiCorp Vault (secrets management) # - PostgreSQL (primary database with configuration system) # - Redis (caching and pub/sub) # - InfluxDB (time series data) # # Usage: docker-compose -f docker-compose.infrastructure.yml up -d #============================================================================ services: #========================================================================== # SECRETS MANAGEMENT #========================================================================== vault: image: hashicorp/vault:1.15.0 container_name: foxhunt-vault-infra 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 && wait " networks: - infrastructure-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" #========================================================================== # PRIMARY DATABASE #========================================================================== postgresql: image: postgres:15.4-alpine container_name: foxhunt-postgres-infra 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 -c log_statement=all -c log_min_duration_statement=1000 networks: - infrastructure-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" #========================================================================== # CACHING & PUB/SUB #========================================================================== redis: image: redis:7.2-alpine container_name: foxhunt-redis-infra 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 --appendonly yes --appendfsync everysec networks: - infrastructure-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" #========================================================================== # TIME SERIES DATABASE #========================================================================== influxdb: image: influxdb:2.7-alpine container_name: foxhunt-influxdb-infra 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: - infrastructure-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" #========================================================================== # DATABASE ADMIN TOOLS (Development Only) #========================================================================== pgadmin: image: dpage/pgadmin4:7.8 container_name: foxhunt-pgadmin-infra hostname: foxhunt-pgadmin ports: - "5050:80" volumes: - pgadmin-data:/var/lib/pgadmin environment: - PGADMIN_DEFAULT_EMAIL=${PGADMIN_EMAIL:-admin@foxhunt.local} - PGADMIN_DEFAULT_PASSWORD=${PGADMIN_PASSWORD:-admin} - PGADMIN_LISTEN_PORT=80 depends_on: postgresql: condition: service_healthy networks: - infrastructure-network restart: unless-stopped healthcheck: test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:80/misc/ping"] interval: 30s timeout: 10s retries: 5 start_period: 30s mem_limit: 512m logging: driver: "json-file" options: max-size: "50m" max-file: "5" redis-commander: image: rediscommander/redis-commander:latest container_name: foxhunt-redis-commander-infra hostname: foxhunt-redis-commander ports: - "8081:8081" environment: - REDIS_HOSTS=local:foxhunt-redis:6379:0:${REDIS_PASSWORD:-foxhunt123} - HTTP_USER=${REDIS_COMMANDER_USER:-admin} - HTTP_PASSWORD=${REDIS_COMMANDER_PASSWORD:-admin} depends_on: redis: condition: service_healthy networks: - infrastructure-network restart: unless-stopped healthcheck: test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:8081/"] interval: 30s timeout: 10s retries: 5 start_period: 30s mem_limit: 256m logging: driver: "json-file" options: max-size: "25m" max-file: "3" #============================================================================== # NETWORKS #============================================================================== networks: infrastructure-network: driver: bridge driver_opts: com.docker.network.bridge.name: foxhunt-infra ipam: config: - subnet: 172.30.0.0/24 gateway: 172.30.0.1 #============================================================================== # VOLUMES #============================================================================== volumes: vault-data: driver: local driver_opts: type: none o: bind device: /opt/foxhunt/vault/data vault-logs: driver: local driver_opts: type: none o: bind device: /opt/foxhunt/vault/logs postgres-data: driver: local driver_opts: type: none o: bind device: /opt/foxhunt/postgres/data redis-data: driver: local driver_opts: type: none o: bind device: /opt/foxhunt/redis/data influxdb-data: driver: local driver_opts: type: none o: bind device: /opt/foxhunt/influxdb/data influxdb-config: driver: local driver_opts: type: none o: bind device: /opt/foxhunt/influxdb/config pgadmin-data: driver: local