# Reference HA topology for a single datacenter. Production requires separate hosts/failure domains.
services:
  pg-0:
    image: bitnami/postgresql-repmgr:16
    environment: &pg_env
      POSTGRESQL_POSTGRES_PASSWORD: ${POSTGRES_SUPERUSER_PASSWORD:-CHANGE_ME}
      POSTGRESQL_USERNAME: datalake
      POSTGRESQL_PASSWORD: ${POSTGRES_PASSWORD:-CHANGE_ME}
      POSTGRESQL_DATABASE: datalake
      REPMGR_PASSWORD: ${REPMGR_PASSWORD:-CHANGE_ME}
      REPMGR_PRIMARY_HOST: pg-0
      REPMGR_PARTNER_NODES: pg-0,pg-1
      REPMGR_NODE_NAME: pg-0
      REPMGR_NODE_NETWORK_NAME: pg-0
    volumes: [pg0_data:/bitnami/postgresql]
    networks: [cedp_ha]
  pg-1:
    image: bitnami/postgresql-repmgr:16
    environment:
      <<: *pg_env
      REPMGR_NODE_NAME: pg-1
      REPMGR_NODE_NETWORK_NAME: pg-1
    volumes: [pg1_data:/bitnami/postgresql]
    networks: [cedp_ha]
  pgpool:
    image: bitnami/pgpool:4
    environment:
      PGPOOL_BACKEND_NODES: 0:pg-0:5432,1:pg-1:5432
      PGPOOL_SR_CHECK_USER: datalake
      PGPOOL_SR_CHECK_PASSWORD: ${POSTGRES_PASSWORD:-CHANGE_ME}
      PGPOOL_ENABLE_LDAP: "no"
      PGPOOL_POSTGRES_USERNAME: postgres
      PGPOOL_POSTGRES_PASSWORD: ${POSTGRES_SUPERUSER_PASSWORD:-CHANGE_ME}
      PGPOOL_ADMIN_USERNAME: admin
      PGPOOL_ADMIN_PASSWORD: ${PGPOOL_ADMIN_PASSWORD:-CHANGE_ME}
    depends_on: [pg-0,pg-1]
    networks: [cedp_ha]
  redis-0:
    image: redis:7-alpine
    command: ["redis-server","--appendonly","yes","--requirepass","${REDIS_PASSWORD:-CHANGE_ME}"]
    volumes: [redis0_data:/data]
    networks: [cedp_ha]
  minio-1:
    image: minio/minio:latest
    command: server http://minio-{1...4}/data --console-address :9001
    environment: &minio_env
      MINIO_ROOT_USER: ${S3_ACCESS_KEY:-datalake_admin}
      MINIO_ROOT_PASSWORD: ${S3_SECRET_KEY:-CHANGE_ME}
    volumes: [minio1_data:/data]
    networks: [cedp_ha]
  minio-2:
    image: minio/minio:latest
    command: server http://minio-{1...4}/data --console-address :9001
    environment: *minio_env
    volumes: [minio2_data:/data]
    networks: [cedp_ha]
  minio-3:
    image: minio/minio:latest
    command: server http://minio-{1...4}/data --console-address :9001
    environment: *minio_env
    volumes: [minio3_data:/data]
    networks: [cedp_ha]
  minio-4:
    image: minio/minio:latest
    command: server http://minio-{1...4}/data --console-address :9001
    environment: *minio_env
    volumes: [minio4_data:/data]
    networks: [cedp_ha]
  api-1:
    build: .
    env_file: .env
    environment:
      METADATA_DATABASE_URL: postgresql+psycopg://datalake:${POSTGRES_PASSWORD:-CHANGE_ME}@pgpool:5432/datalake
      REDIS_URL: redis://:${REDIS_PASSWORD:-CHANGE_ME}@redis-0:6379/0
      S3_ENDPOINT: http://minio-1:9000
      CLUSTER_NODE_NAME: api-1
      CLUSTER_ZONE: zone-a
    command: uvicorn app.main:app --host 0.0.0.0 --port 8080
    depends_on: [pgpool,redis-0,minio-1]
    networks: [cedp_ha]
  api-2:
    build: .
    env_file: .env
    environment:
      METADATA_DATABASE_URL: postgresql+psycopg://datalake:${POSTGRES_PASSWORD:-CHANGE_ME}@pgpool:5432/datalake
      REDIS_URL: redis://:${REDIS_PASSWORD:-CHANGE_ME}@redis-0:6379/0
      S3_ENDPOINT: http://minio-1:9000
      CLUSTER_NODE_NAME: api-2
      CLUSTER_ZONE: zone-b
    command: uvicorn app.main:app --host 0.0.0.0 --port 8080
    depends_on: [pgpool,redis-0,minio-1]
    networks: [cedp_ha]
  worker-1:
    build: .
    env_file: .env
    environment:
      METADATA_DATABASE_URL: postgresql+psycopg://datalake:${POSTGRES_PASSWORD:-CHANGE_ME}@pgpool:5432/datalake
      REDIS_URL: redis://:${REDIS_PASSWORD:-CHANGE_ME}@redis-0:6379/0
      S3_ENDPOINT: http://minio-1:9000
      CLUSTER_NODE_NAME: worker-1
      CLUSTER_NODE_TYPE: worker
    command: celery -A app.workers.celery_app worker --loglevel=INFO --concurrency=2 -n worker1@%h
    networks: [cedp_ha]
  worker-2:
    build: .
    env_file: .env
    environment:
      METADATA_DATABASE_URL: postgresql+psycopg://datalake:${POSTGRES_PASSWORD:-CHANGE_ME}@pgpool:5432/datalake
      REDIS_URL: redis://:${REDIS_PASSWORD:-CHANGE_ME}@redis-0:6379/0
      S3_ENDPOINT: http://minio-1:9000
      CLUSTER_NODE_NAME: worker-2
      CLUSTER_NODE_TYPE: worker
    command: celery -A app.workers.celery_app worker --loglevel=INFO --concurrency=2 -n worker2@%h
    networks: [cedp_ha]
  scheduler:
    build: .
    env_file: .env
    environment:
      METADATA_DATABASE_URL: postgresql+psycopg://datalake:${POSTGRES_PASSWORD:-CHANGE_ME}@pgpool:5432/datalake
      REDIS_URL: redis://:${REDIS_PASSWORD:-CHANGE_ME}@redis-0:6379/0
      S3_ENDPOINT: http://minio-1:9000
      CLUSTER_NODE_NAME: scheduler-1
      CLUSTER_NODE_TYPE: scheduler
    command: celery -A app.workers.celery_app beat --loglevel=INFO
    networks: [cedp_ha]
  haproxy:
    image: haproxy:3.0-alpine
    volumes: ["./infrastructure/ha/haproxy/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro"]
    ports: ["8080:8080"]
    depends_on: [api-1,api-2]
    networks: [cedp_ha]
networks: {cedp_ha: {driver: bridge}}
volumes: {pg0_data: {}, pg1_data: {}, redis0_data: {}, minio1_data: {}, minio2_data: {}, minio3_data: {}, minio4_data: {}}
