version: '3.8'

services:
  # Nginx Load Balancer
  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf
      - ./nginx/ssl:/etc/nginx/ssl
    depends_on:
      - api-gateway-1
      - api-gateway-2
    restart: always

  # API Gateway Cluster
  api-gateway-1:
    image: women-safety/api-gateway:${TAG:-latest}
    environment:
      - NODE_ID=1
      - USER_SERVICE_URL=http://user-service-1:8001,http://user-service-2:8001
      - EMERGENCY_SERVICE_URL=http://emergency-service-1:8002,http://emergency-service-2:8002
      - LOCATION_SERVICE_URL=http://location-service-1:8003,http://location-service-2:8003
      - CALENDAR_SERVICE_URL=http://calendar-service-1:8004,http://calendar-service-2:8004
      - NOTIFICATION_SERVICE_URL=http://notification-service-1:8005,http://notification-service-2:8005
      - REDIS_URL=redis://redis-cluster:6379/0
    depends_on:
      - redis-cluster
    restart: always
    deploy:
      resources:
        limits:
          cpus: '1.0'
          memory: 1G
        reservations:
          cpus: '0.5'
          memory: 512M

  api-gateway-2:
    image: women-safety/api-gateway:${TAG:-latest}
    environment:
      - NODE_ID=2
      - USER_SERVICE_URL=http://user-service-1:8001,http://user-service-2:8001
      - EMERGENCY_SERVICE_URL=http://emergency-service-1:8002,http://emergency-service-2:8002
      - LOCATION_SERVICE_URL=http://location-service-1:8003,http://location-service-2:8003
      - CALENDAR_SERVICE_URL=http://calendar-service-1:8004,http://calendar-service-2:8004
      - NOTIFICATION_SERVICE_URL=http://notification-service-1:8005,http://notification-service-2:8005
      - REDIS_URL=redis://redis-cluster:6379/0
    depends_on:
      - redis-cluster
    restart: always
    deploy:
      resources:
        limits:
          cpus: '1.0'
          memory: 1G

  # User Service Cluster
  user-service-1:
    image: women-safety/user-service:${TAG:-latest}
    environment:
      - NODE_ID=1
      - DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@postgres-primary:5432/women_safety_prod
      - DATABASE_REPLICA_URL=postgresql://postgres:${POSTGRES_PASSWORD}@postgres-replica:5432/women_safety_prod
      - REDIS_URL=redis://redis-cluster:6379/1
      - JWT_SECRET_KEY=${JWT_SECRET_KEY}
    depends_on:
      - postgres-primary
      - redis-cluster
    restart: always
    deploy:
      resources:
        limits:
          cpus: '1.5'
          memory: 2G
        reservations:
          cpus: '0.5'
          memory: 512M

  user-service-2:
    image: women-safety/user-service:${TAG:-latest}
    environment:
      - NODE_ID=2
      - DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@postgres-primary:5432/women_safety_prod
      - DATABASE_REPLICA_URL=postgresql://postgres:${POSTGRES_PASSWORD}@postgres-replica:5432/women_safety_prod
      - REDIS_URL=redis://redis-cluster:6379/1
      - JWT_SECRET_KEY=${JWT_SECRET_KEY}
    depends_on:
      - postgres-primary
      - redis-cluster
    restart: always
    deploy:
      resources:
        limits:
          cpus: '1.5'
          memory: 2G

  # Emergency Service Cluster (High Priority)
  emergency-service-1:
    image: women-safety/emergency-service:${TAG:-latest}
    environment:
      - NODE_ID=1
      - DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@postgres-primary:5432/women_safety_prod
      - REDIS_URL=redis://redis-cluster:6379/2
      - KAFKA_BROKERS=kafka-1:9092,kafka-2:9092,kafka-3:9092
      - LOCATION_SERVICE_URL=http://location-service-1:8003,http://location-service-2:8003
      - NOTIFICATION_SERVICE_URL=http://notification-service-1:8005,http://notification-service-2:8005
    depends_on:
      - postgres-primary
      - redis-cluster
      - kafka-1
    restart: always
    deploy:
      resources:
        limits:
          cpus: '2.0'
          memory: 3G
        reservations:
          cpus: '1.0'
          memory: 1G

  emergency-service-2:
    image: women-safety/emergency-service:${TAG:-latest}
    environment:
      - NODE_ID=2
      - DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@postgres-primary:5432/women_safety_prod
      - REDIS_URL=redis://redis-cluster:6379/2
      - KAFKA_BROKERS=kafka-1:9092,kafka-2:9092,kafka-3:9092
      - LOCATION_SERVICE_URL=http://location-service-1:8003,http://location-service-2:8003
      - NOTIFICATION_SERVICE_URL=http://notification-service-1:8005,http://notification-service-2:8005
    depends_on:
      - postgres-primary
      - redis-cluster
      - kafka-1
    restart: always
    deploy:
      resources:
        limits:
          cpus: '2.0'
          memory: 3G

  # Database Cluster
  postgres-primary:
    image: postgres:15
    environment:
      POSTGRES_DB: women_safety_prod
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      POSTGRES_REPLICATION_MODE: master
      POSTGRES_REPLICATION_USER: replicator
      POSTGRES_REPLICATION_PASSWORD: ${REPLICATION_PASSWORD}
    volumes:
      - postgres_primary_data:/var/lib/postgresql/data
      - ./postgres/postgresql.conf:/etc/postgresql/postgresql.conf
    command: postgres -c config_file=/etc/postgresql/postgresql.conf
    restart: always
    deploy:
      resources:
        limits:
          cpus: '4.0'
          memory: 8G
        reservations:
          cpus: '2.0'
          memory: 4G

  postgres-replica:
    image: postgres:15
    environment:
      POSTGRES_DB: women_safety_prod
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      POSTGRES_MASTER_SERVICE: postgres-primary
      POSTGRES_REPLICATION_MODE: slave
      POSTGRES_REPLICATION_USER: replicator
      POSTGRES_REPLICATION_PASSWORD: ${REPLICATION_PASSWORD}
    volumes:
      - postgres_replica_data:/var/lib/postgresql/data
    depends_on:
      - postgres-primary
    restart: always
    deploy:
      resources:
        limits:
          cpus: '3.0'
          memory: 6G

  # Redis Cluster
  redis-cluster:
    image: redis:7-alpine
    command: redis-server --appendonly yes --cluster-enabled yes
    volumes:
      - redis_data:/data
    restart: always
    deploy:
      resources:
        limits:
          cpus: '1.0'
          memory: 2G

  # Kafka Cluster
  kafka-1:
    image: confluentinc/cp-kafka:latest
    environment:
      KAFKA_BROKER_ID: 1
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka-1:9092
      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 3
      KAFKA_DEFAULT_REPLICATION_FACTOR: 3
      KAFKA_MIN_INSYNC_REPLICAS: 2
    volumes:
      - kafka_1_data:/var/lib/kafka/data
    depends_on:
      - zookeeper
    restart: always

  kafka-2:
    image: confluentinc/cp-kafka:latest
    environment:
      KAFKA_BROKER_ID: 2
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka-2:9092
      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 3
      KAFKA_DEFAULT_REPLICATION_FACTOR: 3
      KAFKA_MIN_INSYNC_REPLICAS: 2
    volumes:
      - kafka_2_data:/var/lib/kafka/data
    depends_on:
      - zookeeper
    restart: always

  kafka-3:
    image: confluentinc/cp-kafka:latest
    environment:
      KAFKA_BROKER_ID: 3
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka-3:9092
      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 3
      KAFKA_DEFAULT_REPLICATION_FACTOR: 3
      KAFKA_MIN_INSYNC_REPLICAS: 2
    volumes:
      - kafka_3_data:/var/lib/kafka/data
    depends_on:
      - zookeeper
    restart: always

  zookeeper:
    image: confluentinc/cp-zookeeper:latest
    environment:
      ZOOKEEPER_CLIENT_PORT: 2181
      ZOOKEEPER_TICK_TIME: 2000
    volumes:
      - zookeeper_data:/var/lib/zookeeper
    restart: always

  # Monitoring
  prometheus:
    image: prom/prometheus:latest
    ports:
      - "9090:9090"
    volumes:
      - ./monitoring/prometheus.yml:/etc/prometheus/prometheus.yml
      - prometheus_data:/prometheus
    restart: always

  grafana:
    image: grafana/grafana:latest
    ports:
      - "3000:3000"
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD}
    volumes:
      - grafana_data:/var/lib/grafana
      - ./monitoring/grafana/dashboards:/etc/grafana/provisioning/dashboards
    depends_on:
      - prometheus
    restart: always

volumes:
  postgres_primary_data:
  postgres_replica_data:
  redis_data:
  kafka_1_data:
  kafka_2_data:
  kafka_3_data:
  zookeeper_data:
  prometheus_data:
  grafana_data: