version: "3.9" services: # ─── Message Broker & Cache ─────────────────────────────────────── redis: image: redis:7-alpine container_name: smartclass-redis ports: - "6379:6379" volumes: - redis_data:/data command: redis-server --appendonly yes --maxmemory 256mb --maxmemory-policy allkeys-lru healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 3s retries: 5 restart: unless-stopped networks: - smartclass-net # ─── Primary Database ───────────────────────────────────────────── postgres: image: postgres:16-alpine container_name: smartclass-postgres ports: - "5432:5432" environment: POSTGRES_USER: ${POSTGRES_USER:-sc_user} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-sc_password} POSTGRES_DB: ${POSTGRES_DB:-smartclass} volumes: - postgres_data:/var/lib/postgresql/data - ./services/api/init_db.sql:/docker-entrypoint-initdb.d/init.sql:ro healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-sc_user} -d ${POSTGRES_DB:-smartclass}"] interval: 10s timeout: 5s retries: 5 restart: unless-stopped networks: - smartclass-net # ─── FastAPI Server ──────────────────────────────────────────────── api: build: context: ./services/api dockerfile: Dockerfile container_name: smartclass-api ports: - "8000:8000" environment: DATABASE_URL: postgresql+asyncpg://${POSTGRES_USER:-sc_user}:${POSTGRES_PASSWORD:-sc_password}@postgres:5432/${POSTGRES_DB:-smartclass} REDIS_URL: redis://redis:6379 JWT_SECRET_KEY: ${JWT_SECRET_KEY:?JWT_SECRET_KEY must be set} CORS_ORIGINS: ${CORS_ORIGINS:-["http://localhost:5173"]} ENVIRONMENT: ${ENVIRONMENT:-development} LOG_LEVEL: ${LOG_LEVEL:-info} depends_on: redis: condition: service_healthy postgres: condition: service_healthy healthcheck: test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://127.0.0.1:8000/health')"] interval: 15s timeout: 5s retries: 3 start_period: 30s restart: unless-stopped networks: - smartclass-net # ─── Background Worker (Redis Consumer) ─────────────────────────── api_worker: build: context: ./services/api dockerfile: Dockerfile container_name: smartclass-worker command: python -m app.worker environment: DATABASE_URL: postgresql+asyncpg://${POSTGRES_USER:-sc_user}:${POSTGRES_PASSWORD:-sc_password}@postgres:5432/${POSTGRES_DB:-smartclass} REDIS_URL: redis://redis:6379 ENVIRONMENT: ${ENVIRONMENT:-development} LOG_LEVEL: ${LOG_LEVEL:-info} depends_on: redis: condition: service_healthy postgres: condition: service_healthy api: condition: service_healthy restart: unless-stopped networks: - smartclass-net # ─── Edge Pipeline (Test Mode) ──────────────────────────────────── edge: build: context: . dockerfile: Dockerfile container_name: smartclass-edge ports: - "9100:9100" environment: REDIS_URL: redis://redis:6379 REDIS_PASSWORD: ${REDIS_PASSWORD:-} EDGE_CONFIG_PATH: /opt/smartclass/config/edge_config.yaml PYTHONPATH: /opt/smartclass/src EDGE_MODE: ${EDGE_MODE:-test} volumes: - ./config:/opt/smartclass/config:ro - ./models:/opt/smartclass/models:ro - ./data:/opt/smartclass/data depends_on: redis: condition: service_healthy healthcheck: test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://127.0.0.1:9100/metrics')"] interval: 15s timeout: 5s retries: 3 start_period: 45s restart: unless-stopped networks: - smartclass-net # ─── Frontend (React + Nginx) ───────────────────────────────────── frontend: build: context: ./frontend dockerfile: Dockerfile args: VITE_API_URL: ${VITE_API_URL:-http://localhost:8000} container_name: smartclass-frontend ports: - "5173:80" depends_on: api: condition: service_healthy healthcheck: test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://127.0.0.1:80/"] interval: 15s timeout: 5s retries: 3 restart: unless-stopped networks: - smartclass-net # ─── Metrics Collection ─────────────────────────────────────────── prometheus: image: prom/prometheus:v2.51.0 container_name: smartclass-prometheus ports: - "9090:9090" volumes: - ./monitoring/prometheus.yml:/etc/prometheus/prometheus.yml:ro - ./monitoring/smartclass_alerts.yml:/etc/prometheus/rules/smartclass_alerts.yml:ro - prometheus_data:/prometheus command: - '--config.file=/etc/prometheus/prometheus.yml' - '--storage.tsdb.path=/prometheus' - '--storage.tsdb.retention.time=30d' - '--web.enable-lifecycle' depends_on: - api - edge healthcheck: test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://127.0.0.1:9090/-/healthy"] interval: 15s timeout: 5s retries: 3 restart: unless-stopped networks: - smartclass-net volumes: redis_data: postgres_data: prometheus_data: networks: smartclass-net: driver: bridge