# Production MEV Bot Docker Compose Configuration version: '3.8' services: # Main MEV Bot Service mev-bot: build: context: . dockerfile: Dockerfile.production target: production container_name: mev-bot-arbitrum restart: unless-stopped # Environment configuration environment: # Arbitrum Network Configuration - ARBITRUM_RPC_ENDPOINT=${ARBITRUM_RPC_ENDPOINT:-wss://arbitrum-mainnet.core.chainstack.com/53c30e7a941160679fdcc396c894fc57} - ARBITRUM_WS_ENDPOINT=${ARBITRUM_WS_ENDPOINT:-wss://arbitrum-mainnet.core.chainstack.com/53c30e7a941160679fdcc396c894fc57} - ARBITRUM_FALLBACK_ENDPOINTS=${ARBITRUM_FALLBACK_ENDPOINTS:-https://arb1.arbitrum.io/rpc,https://arbitrum.llamarpc.com,https://arbitrum-one.publicnode.com} # Rate limiting - RPC_REQUESTS_PER_SECOND=${RPC_REQUESTS_PER_SECOND:-100} - RPC_MAX_CONCURRENT=${RPC_MAX_CONCURRENT:-10} # Bot Configuration - BOT_MAX_WORKERS=${BOT_MAX_WORKERS:-5} - BOT_CHANNEL_BUFFER_SIZE=${BOT_CHANNEL_BUFFER_SIZE:-1000} # Ethereum Account (NEVER set in compose file - use .env file) - ETHEREUM_PRIVATE_KEY=${ETHEREUM_PRIVATE_KEY} - ETHEREUM_ACCOUNT_ADDRESS=${ETHEREUM_ACCOUNT_ADDRESS} - ETHEREUM_GAS_PRICE_MULTIPLIER=${ETHEREUM_GAS_PRICE_MULTIPLIER:-1.5} # Smart Contract Addresses - CONTRACT_ARBITRAGE_EXECUTOR=${CONTRACT_ARBITRAGE_EXECUTOR} - CONTRACT_FLASH_SWAPPER=${CONTRACT_FLASH_SWAPPER} # Security - MEV_BOT_ENCRYPTION_KEY=${MEV_BOT_ENCRYPTION_KEY} # Logging and Monitoring - LOG_LEVEL=${LOG_LEVEL:-info} - LOG_FORMAT=${LOG_FORMAT:-json} - METRICS_ENABLED=${METRICS_ENABLED:-true} - METRICS_PORT=${METRICS_PORT:-9090} # Production Environment - GO_ENV=production - DEBUG=false # Volume mounts for persistent data volumes: - ./data:/app/data:Z - ./logs:/app/logs:Z - ./config:/app/config:ro - ./keys:/app/keys:ro,Z # Read-only keys directory # Port exposure ports: - "${METRICS_PORT:-9090}:9090" # Metrics endpoint - "${HEALTH_PORT:-8080}:8080" # Health check endpoint # Health check healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8080/health"] interval: 30s timeout: 10s retries: 3 start_period: 60s # Resource limits deploy: resources: limits: memory: 1G cpus: '2.0' reservations: memory: 512M cpus: '1.0' # Logging configuration logging: driver: "json-file" options: max-size: "100m" max-file: "5" # Security security_opt: - no-new-privileges:true read_only: true tmpfs: - /tmp:noexec,nosuid,size=100m # Dependencies depends_on: - redis - postgres # Networks networks: - mev-bot-network # Redis for caching and rate limiting redis: image: redis:7-alpine container_name: mev-bot-redis restart: unless-stopped # Redis configuration command: redis-server --appendonly yes --maxmemory 256mb --maxmemory-policy allkeys-lru volumes: - redis_data:/data:Z # Security security_opt: - no-new-privileges:true read_only: true tmpfs: - /tmp:noexec,nosuid,size=10m # Resource limits deploy: resources: limits: memory: 512M cpus: '0.5' # Health check healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 30s timeout: 5s retries: 3 networks: - mev-bot-network # PostgreSQL for transaction and profit tracking postgres: image: postgres:15-alpine container_name: mev-bot-postgres restart: unless-stopped environment: - POSTGRES_DB=${POSTGRES_DB:-mevbot} - POSTGRES_USER=${POSTGRES_USER:-mevbot} - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} - POSTGRES_INITDB_ARGS=--auth-host=scram-sha-256 volumes: - postgres_data:/var/lib/postgresql/data:Z - ./scripts/init-db.sql:/docker-entrypoint-initdb.d/init-db.sql:ro # Security security_opt: - no-new-privileges:true # Resource limits deploy: resources: limits: memory: 1G cpus: '1.0' # Health check healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-mevbot}"] interval: 30s timeout: 5s retries: 3 networks: - mev-bot-network # Prometheus for metrics collection prometheus: image: prom/prometheus:latest container_name: mev-bot-prometheus restart: unless-stopped command: - '--config.file=/etc/prometheus/prometheus.yml' - '--storage.tsdb.path=/prometheus' - '--web.console.libraries=/etc/prometheus/console_libraries' - '--web.console.templates=/etc/prometheus/consoles' - '--storage.tsdb.retention.time=30d' - '--web.enable-lifecycle' volumes: - ./monitoring/prometheus.yml:/etc/prometheus/prometheus.yml:ro - prometheus_data:/prometheus:Z ports: - "${PROMETHEUS_PORT:-9091}:9090" # Security security_opt: - no-new-privileges:true networks: - mev-bot-network # Grafana for monitoring dashboards grafana: image: grafana/grafana:latest container_name: mev-bot-grafana restart: unless-stopped environment: - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD:-admin123} - GF_SECURITY_ADMIN_USER=${GRAFANA_USER:-admin} - GF_INSTALL_PLUGINS=grafana-clock-panel,grafana-simple-json-datasource volumes: - grafana_data:/var/lib/grafana:Z - ./monitoring/grafana/dashboards:/etc/grafana/provisioning/dashboards:ro - ./monitoring/grafana/datasources:/etc/grafana/provisioning/datasources:ro ports: - "${GRAFANA_PORT:-3000}:3000" # Security security_opt: - no-new-privileges:true depends_on: - prometheus networks: - mev-bot-network # Log aggregation with Fluentd # Node Exporter for system metrics node-exporter: image: quay.io/prometheus/node-exporter:latest container_name: mev-bot-node-exporter restart: unless-stopped command: - '--path.rootfs=/host' volumes: - '/:/host:ro,rslave' ports: - "9100:9100" # Security security_opt: - no-new-privileges:true read_only: true tmpfs: - /tmp:noexec,nosuid,size=10m networks: - mev-bot-network fluentd: build: context: ./monitoring/fluentd dockerfile: Dockerfile container_name: mev-bot-fluentd restart: unless-stopped volumes: - ./monitoring/fluentd/conf:/fluentd/etc:ro - ./logs:/fluentd/logs:ro ports: - "24224:24224" - "24224:24224/udp" networks: - mev-bot-network # Named volumes for data persistence volumes: redis_data: driver: local postgres_data: driver: local prometheus_data: driver: local grafana_data: driver: local # Network configuration networks: mev-bot-network: driver: bridge ipam: config: - subnet: 172.20.0.0/16