version: "3.8" # This file works both locally and on EC2 for demo purposes. # For local dev with hot-reload, use: docker compose -f docker-compose.yml -f docker-compose.override.yml up x-common-env: &common-env REDIS_URL: redis://redis:6379 TIMESCALE_URL: postgresql://monitor:monitor@timescaledb:5432/monitor EVENTS_BACKEND: redis_pubsub LOG_LEVEL: ${LOG_LEVEL:-INFO} LOG_FORMAT: json x-healthcheck-defaults: &healthcheck-defaults interval: 10s timeout: 5s retries: 3 start_period: 10s services: # ============================================================================= # Infrastructure # ============================================================================= redis: image: redis:7-alpine ports: - "${REDIS_PORT:-6379}:6379" volumes: - redis-data:/data healthcheck: <<: *healthcheck-defaults test: ["CMD", "redis-cli", "ping"] deploy: resources: limits: memory: 128M timescaledb: image: timescale/timescaledb:latest-pg15 environment: POSTGRES_USER: monitor POSTGRES_PASSWORD: monitor POSTGRES_DB: monitor ports: - "${TIMESCALE_PORT:-5432}:5432" volumes: - timescale-data:/var/lib/postgresql/data - ./scripts/init-db.sql:/docker-entrypoint-initdb.d/init.sql:ro healthcheck: <<: *healthcheck-defaults test: ["CMD-SHELL", "pg_isready -U monitor -d monitor"] deploy: resources: limits: memory: 512M # ============================================================================= # Application Services # ============================================================================= aggregator: build: context: . dockerfile: services/aggregator/Dockerfile environment: <<: *common-env GRPC_PORT: 50051 SERVICE_NAME: aggregator ports: - "${AGGREGATOR_GRPC_PORT:-50051}:50051" depends_on: redis: condition: service_healthy timescaledb: condition: service_healthy healthcheck: <<: *healthcheck-defaults test: ["CMD", "/bin/grpc_health_probe", "-addr=:50051"] deploy: resources: limits: memory: 256M gateway: build: context: . dockerfile: services/gateway/Dockerfile environment: <<: *common-env HTTP_PORT: 8000 AGGREGATOR_URL: aggregator:50051 SERVICE_NAME: gateway ports: - "${GATEWAY_PORT:-8000}:8000" depends_on: - aggregator - redis healthcheck: <<: *healthcheck-defaults test: ["CMD", "curl", "-f", "http://localhost:8000/health"] deploy: resources: limits: memory: 256M alerts: build: context: . dockerfile: services/alerts/Dockerfile environment: <<: *common-env SERVICE_NAME: alerts depends_on: redis: condition: service_healthy timescaledb: condition: service_healthy healthcheck: <<: *healthcheck-defaults test: ["CMD", "python", "-c", "import sys; sys.exit(0)"] deploy: resources: limits: memory: 128M # Collector runs separately on each machine being monitored # For local testing, we run one instance collector: build: context: . dockerfile: services/collector/Dockerfile environment: <<: *common-env AGGREGATOR_URL: aggregator:50051 MACHINE_ID: ${MACHINE_ID:-local-dev} COLLECTION_INTERVAL: ${COLLECTION_INTERVAL:-5} SERVICE_NAME: collector depends_on: - aggregator deploy: resources: limits: memory: 64M # For actual system metrics, you might need: # privileged: true # pid: host volumes: redis-data: timescale-data: networks: default: name: sysmonstm