# Compose v2

x-common-env: &common-env
  env_file:
    - ../env/.env.runtime

volumes:
  mongo1_data: {}
  mongo2_data: {}
  mongo3_data: {}
  # In-memory store for secrets/material rendered by Vault Agent (no host persistence)
  vault_secrets:
    driver: local
    driver_opts:
      type: tmpfs
      device: tmpfs
      o: size=32m,uid=999,gid=999,mode=0750
  # In-memory config for PBM (rendered from templates, no host persistence)
  pbm_cfg:
    driver: local
    driver_opts:
      type: tmpfs
      device: tmpfs
      o: size=16m,uid=0,gid=0,mode=0750

networks:
  sendico-net:
    external: true
    name: sendico-net

services:
  vault-agent-sendico:
    <<: *common-env
    image: hashicorp/vault:latest
    container_name: vault-agent-sendico
    restart: unless-stopped
    cap_add: ["IPC_LOCK"]
    # VAULT_ADDR is required by the agent and comes from ../env/.env.runtime
    # VAULT_ROLE_ID / VAULT_SECRET_ID are passed only during `docker compose` from CI
    environment:
      VAULT_ADDR: ${VAULT_ADDR}
      VAULT_ROLE_ID: ${VAULT_ROLE_ID}
      VAULT_SECRET_ID: ${VAULT_SECRET_ID}
    volumes:
      - ./vault/agent.hcl:/etc/vault/agent.hcl:ro
      - ./vault/templates:/etc/vault/templates:ro
      - vault_secrets:/vault/secrets:rw
      - pbm_cfg:/etc/backup:rw
    # Write AppRole creds into tmpfs, unset them from env, then exec the agent
    # Note: use $${...} here to avoid compose-time interpolation
    command: >
      sh -lc 'set -euo pipefail; umask 077;
              : "$${VAULT_ADDR:?}"; : "$${VAULT_ROLE_ID:?}"; : "$${VAULT_SECRET_ID:?}";
              printf "%s" "$${VAULT_ROLE_ID}"   > /vault/secrets/role_id;
              printf "%s" "$${VAULT_SECRET_ID}" > /vault/secrets/secret_id;
              unset VAULT_ROLE_ID VAULT_SECRET_ID;
              exec vault agent -config=/etc/vault/agent.hcl'
    healthcheck:
      test: ["CMD-SHELL","test -s /vault/secrets/MONGO_INITDB_ROOT_USERNAME -a -s /vault/secrets/MONGO_INITDB_ROOT_PASSWORD -a -s /vault/secrets/mongo.kf -a -s /etc/backup/pbm.env -a -s /etc/backup/.u -a -s /etc/backup/.p"]
      interval: 5s
      timeout: 3s
      retries: 30
      start_period: 5s
    networks:
      - sendico-net

  sendico_db1:
    <<: *common-env
    image: docker.io/library/mongo:latest
    container_name: sendico_db1
    restart: unless-stopped
    depends_on:
      vault-agent-sendico:
        condition: service_healthy
    entrypoint: ["/usr/local/bin/mongo-entrypoint-wrapper.sh"]
    command: >
      mongod --replSet ${MONGO_REPLICA_SET} --bind_ip_all --auth
             --keyFile /vault/secrets/mongo.kf --port ${MONGO_PORT}
    volumes:
      - mongo1_data:/data/db
      - vault_secrets:/vault/secrets:ro
      - ./ops/mongo-entrypoint.sh:/usr/local/bin/mongo-entrypoint-wrapper.sh:ro
    healthcheck:
      test: ["CMD-SHELL","mongosh --quiet --host localhost --port ${MONGO_PORT} --eval 'db.runCommand({ ping: 1 }).ok' || exit 1"]
      interval: 10s
      timeout: 5s
      retries: 10
      start_period: 30s
    ports: [ "0.0.0.0:${MONGO_PORT}:${MONGO_PORT}" ]
    networks:
      - sendico-net

  sendico_db2:
    <<: *common-env
    image: docker.io/library/mongo:latest
    container_name: sendico_db2
    restart: unless-stopped
    depends_on:
      vault-agent-sendico:
        condition: service_healthy
    entrypoint: ["/usr/local/bin/mongo-entrypoint-wrapper.sh"]
    command: >
      mongod --replSet ${MONGO_REPLICA_SET} --bind_ip_all --auth
             --keyFile /vault/secrets/mongo.kf --port ${MONGO_PORT}
    volumes:
      - mongo2_data:/data/db
      - vault_secrets:/vault/secrets:ro
      - ./ops/mongo-entrypoint.sh:/usr/local/bin/mongo-entrypoint-wrapper.sh:ro
    healthcheck:
      test: ["CMD-SHELL","mongosh --quiet --host localhost --port ${MONGO_PORT} --eval 'db.runCommand({ ping: 1 }).ok' || exit 1"]
      interval: 10s
      timeout: 5s
      retries: 10
      start_period: 30s
    networks:
      - sendico-net

  sendico_db3:
    <<: *common-env
    image: docker.io/library/mongo:latest
    container_name: sendico_db3
    restart: unless-stopped
    depends_on:
      vault-agent-sendico:
        condition: service_healthy
    entrypoint: ["/usr/local/bin/mongo-entrypoint-wrapper.sh"]
    command: >
      mongod --replSet ${MONGO_REPLICA_SET} --bind_ip_all --auth
             --keyFile /vault/secrets/mongo.kf --port ${MONGO_PORT}
    volumes:
      - mongo3_data:/data/db
      - vault_secrets:/vault/secrets:ro
      - ./ops/mongo-entrypoint.sh:/usr/local/bin/mongo-entrypoint-wrapper.sh:ro
    healthcheck:
      test: ["CMD-SHELL","mongosh --quiet --host localhost --port ${MONGO_PORT} --eval 'db.runCommand({ ping: 1 }).ok' || exit 1"]
      interval: 10s
      timeout: 5s
      retries: 10
      start_period: 30s
    networks:
      - sendico-net

  mongo_setup:
    <<: *common-env
    image: docker.io/library/mongo:latest
    depends_on:
      sendico_db1: { condition: service_healthy }
      sendico_db2: { condition: service_healthy }
      sendico_db3: { condition: service_healthy }
    volumes:
      - vault_secrets:/vault/secrets:ro
    entrypoint: |
      bash -c '
        set -euo pipefail
        u=$(cat /vault/secrets/MONGO_INITDB_ROOT_USERNAME)
        p=$(cat /vault/secrets/MONGO_INITDB_ROOT_PASSWORD)
        until mongosh --quiet --host sendico_db1 --port ${MONGO_PORT} --eval "db.adminCommand({ ping: 1 })"; do
          echo "waiting for MongoDB…"; sleep 2;
        done
        mongosh --host sendico_db1 --port ${MONGO_PORT} -u "$$u" -p "$$p" --authenticationDatabase admin <<'EOJS'
          try { rs.status() } catch (e) {
            rs.initiate({
              _id: "${MONGO_REPLICA_SET}",
              members: [
                { _id: 0, host: "sendico_db1:${MONGO_PORT}", priority: 2 },
                { _id: 1, host: "sendico_db2:${MONGO_PORT}", priority: 1 },
                { _id: 2, host: "sendico_db3:${MONGO_PORT}", priority: 1 }
              ]
            })
          }
        EOJS
      '
    restart: "no"
    networks:
      - sendico-net

  pbm-agent-1:
    <<: *common-env
    image: percona/percona-backup-mongodb:latest
    container_name: pbm-agent-1
    restart: unless-stopped
    depends_on:
      sendico_db1: { condition: service_healthy }
      vault-agent-sendico: { condition: service_healthy }
    volumes:
      - pbm_cfg:/etc/backup:ro
    command: |
      sh -lc '
        set -euo pipefail
        set -a
        . /etc/backup/pbm.env
        set +a
        U=$$(cat /etc/backup/.u) ; P=$$(cat /etc/backup/.p)
        export AWS_EC2_METADATA_DISABLED=true
        export PBM_MONGODB_URI="mongodb://$${U}:$${P}@sendico_db1:${MONGO_PORT}/?authSource=${MONGO_AUTH_SOURCE}&replicaSet=${MONGO_REPLICA_SET}"
        exec pbm-agent --config=/etc/backup/pbm-config.yaml
      '
    networks:
      - sendico-net

  pbm-agent-2:
    <<: *common-env
    image: percona/percona-backup-mongodb:latest
    container_name: pbm-agent-2
    restart: unless-stopped
    depends_on:
      sendico_db2: { condition: service_healthy }
      vault-agent-sendico: { condition: service_healthy }
    volumes:
      - pbm_cfg:/etc/backup:ro
    command: |
      sh -lc '
        set -euo pipefail
        set -a
        . /etc/backup/pbm.env
        set +a
        U=$$(cat /etc/backup/.u) ; P=$$(cat /etc/backup/.p)
        export AWS_EC2_METADATA_DISABLED=true
        export PBM_MONGODB_URI="mongodb://$${U}:$${P}@sendico_db2:${MONGO_PORT}/?authSource=${MONGO_AUTH_SOURCE}&replicaSet=${MONGO_REPLICA_SET}"
        exec pbm-agent --config=/etc/backup/pbm-config.yaml
      '
    networks:
      - sendico-net

  pbm-agent-3:
    <<: *common-env
    image: percona/percona-backup-mongodb:latest
    container_name: pbm-agent-3
    restart: unless-stopped
    depends_on:
      sendico_db3: { condition: service_healthy }
      vault-agent-sendico: { condition: service_healthy }
    volumes:
      - pbm_cfg:/etc/backup:ro
    command: |
      sh -lc '
        set -euo pipefail
        set -a
        . /etc/backup/pbm.env
        set +a
        U=$$(cat /etc/backup/.u) ; P=$$(cat /etc/backup/.p)
        export AWS_EC2_METADATA_DISABLED=true
        export PBM_MONGODB_URI="mongodb://$${U}:$${P}@sendico_db3:${MONGO_PORT}/?authSource=${MONGO_AUTH_SOURCE}&replicaSet=${MONGO_REPLICA_SET}"
        exec pbm-agent --config=/etc/backup/pbm-config.yaml
      '
    networks:
      - sendico-net

