version: '3.8' services: postgres: image: postgres:16-alpine container_name: sim-orchestrator-postgres environment: POSTGRES_USER: postgres POSTGRES_PASSWORD: postgres POSTGRES_DB: sim_orchestrator ports: - "5432:5432" volumes: - postgres_data:/var/lib/postgresql/data - ./scripts/init-db.sql:/docker-entrypoint-initdb.d/init-db.sql:ro healthcheck: test: ["CMD-SHELL", "pg_isready -U postgres"] interval: 10s timeout: 5s retries: 5 redis: image: redis:7-alpine container_name: sim-orchestrator-redis ports: - "6379:6379" volumes: - redis_data:/data healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 5 minio: image: minio/minio:latest container_name: sim-orchestrator-minio command: server /data --console-address ":9001" environment: MINIO_ROOT_USER: minioadmin MINIO_ROOT_PASSWORD: minioadmin ports: - "9000:9000" - "9001:9001" volumes: - minio_data:/data healthcheck: test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"] interval: 30s timeout: 20s retries: 3 api: build: context: ./backend dockerfile: Dockerfile container_name: sim-orchestrator-api environment: DATABASE_URL: postgresql+asyncpg://postgres:postgres@postgres:5432/sim_orchestrator REDIS_URL: redis://redis:6379/0 CORS_ORIGINS: '["http://localhost:3000", "http://localhost:5173"]' SECRET_KEY: dev-secret-key-change-in-production-min-32-chars DEBUG: "true" LOG_LEVEL: "DEBUG" S3_ENDPOINT_URL: http://minio:9000 S3_ACCESS_KEY: minioadmin S3_SECRET_KEY: minioadmin S3_BUCKET_PROFILES: sim-profiles S3_REGION: us-east-1 OTEL_EXPORTER_OTLP_ENDPOINT: http://otel-collector:4317 ports: - "8000:8000" depends_on: postgres: condition: service_healthy redis: condition: service_healthy minio: condition: service_healthy volumes: - ./backend:/app command: uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload worker: build: context: ./backend dockerfile: Dockerfile container_name: sim-orchestrator-worker environment: DATABASE_URL: postgresql+asyncpg://postgres:postgres@postgres:5432/sim_orchestrator REDIS_URL: redis://redis:6379/0 CELERY_BROKER_URL: redis://redis:6379/1 CELERY_RESULT_BACKEND: redis://redis:6379/2 DEBUG: "true" depends_on: postgres: condition: service_healthy redis: condition: service_healthy volumes: - ./backend:/app command: celery -A app.workers.celery_app worker --loglevel=info --concurrency=4 frontend: build: context: ./frontend dockerfile: Dockerfile container_name: sim-orchestrator-frontend environment: VITE_API_URL: http://localhost:8000/api/v1 ports: - "3000:3000" depends_on: - api volumes: - ./frontend:/app - /app/node_modules prometheus: image: prom/prometheus:v2.52.0 container_name: sim-orchestrator-prometheus ports: - "9090:9090" volumes: - ./docker/prometheus.yml:/etc/prometheus/prometheus.yml:ro - prometheus_data:/prometheus command: - '--config.file=/etc/prometheus/prometheus.yml' - '--storage.tsdb.path=/prometheus' - '--web.console.libraries=/etc/prometheus/console_libraries' - '--web.console.templates=/etc/prometheus/consoles' grafana: image: grafana/grafana:10.3.1 container_name: sim-orchestrator-grafana ports: - "3001:3000" environment: GF_SECURITY_ADMIN_USER: admin GF_SECURITY_ADMIN_PASSWORD: admin GF_USERS_ALLOW_SIGN_UP: "false" volumes: - grafana_data:/var/lib/grafana - ./docker/grafana/dashboards:/etc/grafana/provisioning/dashboards:ro - ./docker/grafana/datasources:/etc/grafana/provisioning/datasources:ro depends_on: - prometheus otel-collector: image: otel/opentelemetry-collector-contrib:0.106.0 container_name: sim-orchestrator-otel ports: - "4317:4317" - "4318:4318" - "8888:8888" volumes: - ./docker/otel-collector-config.yml:/etc/otelcol-contrib/config.yml:ro depends_on: - prometheus volumes: postgres_data: redis_data: minio_data: prometheus_data: grafana_data: