version: '3.8' services: # PostgreSQL + PostGIS postgres: image: postgis/postgis:15-3.3 container_name: iom-postgres environment: POSTGRES_DB: iom POSTGRES_USER: iom POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-iom_secret} volumes: - postgres_data:/var/lib/postgresql/data - ./database/schema.sql:/docker-entrypoint-initdb.d/01-schema.sql - ./database/seed.sql:/docker-entrypoint-initdb.d/02-seed.sql ports: - "5432:5432" healthcheck: test: ["CMD-SHELL", "pg_isready -U iom"] interval: 10s timeout: 5s retries: 5 networks: - iom-network # Redis (cache + message broker) redis: image: redis:7-alpine container_name: iom-redis ports: - "6379:6379" volumes: - redis_data:/data healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 5 networks: - iom-network # IOM API api: build: context: . dockerfile: Dockerfile container_name: iom-api environment: DATABASE_URL: postgresql://iom:${POSTGRES_PASSWORD:-iom_secret}@postgres:5432/iom REDIS_URL: redis://redis:6379/0 JWT_SECRET: ${JWT_SECRET:-iom_jwt_secret} ENVIRONMENT: ${ENVIRONMENT:-production} LOG_LEVEL: ${LOG_LEVEL:-INFO} ports: - "8000:8000" depends_on: postgres: condition: service_healthy redis: condition: service_healthy volumes: - ./logs:/app/logs networks: - iom-network restart: unless-stopped # Celery Worker (background jobs) worker: build: context: . dockerfile: Dockerfile.worker container_name: iom-worker environment: DATABASE_URL: postgresql://iom:${POSTGRES_PASSWORD:-iom_secret}@postgres:5432/iom REDIS_URL: redis://redis:6379/0 CELERY_BROKER_URL: redis://redis:6379/1 CELERY_RESULT_BACKEND: redis://redis:6379/2 depends_on: - redis - postgres networks: - iom-network restart: unless-stopped # Celery Beat (scheduled tasks) beat: build: context: . dockerfile: Dockerfile.worker container_name: iom-beat command: celery -A tasks beat --loglevel=info environment: DATABASE_URL: postgresql://iom:${POSTGRES_PASSWORD:-iom_secret}@postgres:5432/iom REDIS_URL: redis://redis:6379/0 CELERY_BROKER_URL: redis://redis:6379/1 CELERY_RESULT_BACKEND: redis://redis:6379/2 depends_on: - redis - postgres networks: - iom-network restart: unless-stopped # Nginx (reverse proxy + load balancer) nginx: image: nginx:alpine container_name: iom-nginx ports: - "80:80" - "443:443" volumes: - ./nginx/nginx.conf:/etc/nginx/nginx.conf - ./nginx/ssl:/etc/nginx/ssl depends_on: - api networks: - iom-network restart: unless-stopped # Prometheus (metrics) prometheus: image: prom/prometheus:latest container_name: iom-prometheus ports: - "9090:9090" volumes: - ./monitoring/prometheus.yml:/etc/prometheus/prometheus.yml - prometheus_data:/prometheus networks: - iom-network # Grafana (dashboards) grafana: image: grafana/grafana:latest container_name: iom-grafana ports: - "3000:3000" environment: GF_SECURITY_ADMIN_PASSWORD: ${GRAFANA_PASSWORD:-admin} volumes: - grafana_data:/var/lib/grafana - ./monitoring/dashboards:/etc/grafana/provisioning/dashboards networks: - iom-network volumes: postgres_data: redis_data: prometheus_data: grafana_data: networks: iom-network: driver: bridge