# Apache Pulsar Docker Compose
# Provides standalone mode by default and cluster mode via profile

x-defaults: &defaults
  restart: unless-stopped
  logging:
    driver: json-file
    options:
      max-size: 100m
      max-file: '3'

services:
  # Standalone mode (default) - single node deployment for development/testing
  pulsar:
    <<: *defaults
    image: ${GLOBAL_REGISTRY:-}apachepulsar/pulsar:${PULSAR_VERSION:-4.0.7}
    profiles:
      - ''
    hostname: pulsar-standalone
    ports:
      - '${PULSAR_BROKER_PORT_OVERRIDE:-6650}:6650'
      - '${PULSAR_HTTP_PORT_OVERRIDE:-8080}:8080'
    volumes:
      - pulsar_data:/pulsar/data
      - pulsar_conf:/pulsar/conf
    environment:
      - TZ=${TZ:-UTC}
      - PULSAR_MEM=${PULSAR_MEM:--Xms512m -Xmx512m -XX:MaxDirectMemorySize=256m}
      - PULSAR_STANDALONE_USE_ZOOKEEPER=${PULSAR_STANDALONE_USE_ZOOKEEPER:-0}
    command: sh -c "bin/apply-config-from-env.py conf/standalone.conf && bin/pulsar standalone --no-functions-worker"
    deploy:
      resources:
        limits:
          cpus: ${PULSAR_CPU_LIMIT:-2.00}
          memory: ${PULSAR_MEMORY_LIMIT:-2G}
        reservations:
          cpus: ${PULSAR_CPU_RESERVATION:-0.50}
          memory: ${PULSAR_MEMORY_RESERVATION:-512M}
    healthcheck:
      test: [CMD-SHELL, 'bin/pulsar-admin brokers healthcheck || exit 1']
      interval: 30s
      timeout: 10s
      retries: 5
      start_period: 90s

  # ==================== Cluster Mode (profile: cluster) ====================

  # ZooKeeper for cluster coordination
  zookeeper:
    <<: *defaults
    image: ${GLOBAL_REGISTRY:-}apachepulsar/pulsar:${PULSAR_VERSION:-4.0.7}
    profiles:
      - cluster
    volumes:
      - zookeeper_data:/pulsar/data/zookeeper
    environment:
      - TZ=${TZ:-UTC}
      - metadataStoreUrl=zk:zookeeper:2181
      - PULSAR_MEM=${ZOOKEEPER_MEM:--Xms256m -Xmx256m -XX:MaxDirectMemorySize=256m}
    command: >
      bash -c "bin/apply-config-from-env.py conf/zookeeper.conf &&
      bin/generate-zookeeper-config.sh conf/zookeeper.conf &&
      exec bin/pulsar zookeeper"
    deploy:
      resources:
        limits:
          cpus: ${ZOOKEEPER_CPU_LIMIT:-1.00}
          memory: ${ZOOKEEPER_MEMORY_LIMIT:-512M}
        reservations:
          cpus: ${ZOOKEEPER_CPU_RESERVATION:-0.25}
          memory: ${ZOOKEEPER_MEMORY_RESERVATION:-256M}
    healthcheck:
      test: [CMD, bin/pulsar-zookeeper-ruok.sh]
      interval: 10s
      timeout: 5s
      retries: 30
      start_period: 10s

  # Initialize cluster metadata
  pulsar-init:
    image: ${GLOBAL_REGISTRY:-}apachepulsar/pulsar:${PULSAR_VERSION:-4.0.7}
    profiles:
      - cluster
    environment:
      - TZ=${TZ:-UTC}
    command: >
      bash -c "bin/pulsar initialize-cluster-metadata
      --cluster ${PULSAR_CLUSTER_NAME:-cluster-a}
      --zookeeper zookeeper:2181
      --configuration-store zookeeper:2181
      --web-service-url http://broker:8080
      --broker-service-url pulsar://broker:6650"
    depends_on:
      zookeeper:
        condition: service_healthy

  # BookKeeper (Bookie) for message storage
  bookie:
    <<: *defaults
    image: ${GLOBAL_REGISTRY:-}apachepulsar/pulsar:${PULSAR_VERSION:-4.0.7}
    profiles:
      - cluster
    volumes:
      - bookie_data:/pulsar/data/bookkeeper
    environment:
      - TZ=${TZ:-UTC}
      - clusterName=${PULSAR_CLUSTER_NAME:-cluster-a}
      - zkServers=zookeeper:2181
      - metadataServiceUri=metadata-store:zk:zookeeper:2181
      - advertisedAddress=bookie
      - BOOKIE_MEM=${BOOKIE_MEM:--Xms512m -Xmx512m -XX:MaxDirectMemorySize=256m}
    command: bash -c "bin/apply-config-from-env.py conf/bookkeeper.conf && exec bin/pulsar bookie"
    depends_on:
      zookeeper:
        condition: service_healthy
      pulsar-init:
        condition: service_completed_successfully
    deploy:
      resources:
        limits:
          cpus: ${BOOKIE_CPU_LIMIT:-1.00}
          memory: ${BOOKIE_MEMORY_LIMIT:-1G}
        reservations:
          cpus: ${BOOKIE_CPU_RESERVATION:-0.25}
          memory: ${BOOKIE_MEMORY_RESERVATION:-512M}
    healthcheck:
      test: [CMD, bin/bookkeeper, shell, bookiesanity]
      interval: 30s
      timeout: 10s
      retries: 5
      start_period: 30s

  # Pulsar Broker for cluster mode
  broker:
    <<: *defaults
    image: ${GLOBAL_REGISTRY:-}apachepulsar/pulsar:${PULSAR_VERSION:-4.0.7}
    profiles:
      - cluster
    ports:
      - '${PULSAR_BROKER_PORT_OVERRIDE:-6650}:6650'
      - '${PULSAR_HTTP_PORT_OVERRIDE:-8080}:8080'
    environment:
      - TZ=${TZ:-UTC}
      - metadataStoreUrl=zk:zookeeper:2181
      - zookeeperServers=zookeeper:2181
      - clusterName=${PULSAR_CLUSTER_NAME:-cluster-a}
      - managedLedgerDefaultEnsembleSize=1
      - managedLedgerDefaultWriteQuorum=1
      - managedLedgerDefaultAckQuorum=1
      - advertisedAddress=broker
      - advertisedListeners=external:pulsar://127.0.0.1:6650
      - PULSAR_MEM=${BROKER_MEM:--Xms512m -Xmx512m -XX:MaxDirectMemorySize=256m}
    command: bash -c "bin/apply-config-from-env.py conf/broker.conf && exec bin/pulsar broker"
    depends_on:
      zookeeper:
        condition: service_healthy
      bookie:
        condition: service_healthy
    deploy:
      resources:
        limits:
          cpus: ${BROKER_CPU_LIMIT:-2.00}
          memory: ${BROKER_MEMORY_LIMIT:-2G}
        reservations:
          cpus: ${BROKER_CPU_RESERVATION:-0.50}
          memory: ${BROKER_MEMORY_RESERVATION:-512M}
    healthcheck:
      test: [CMD, bin/pulsar-admin, brokers, healthcheck]
      interval: 30s
      timeout: 10s
      retries: 5
      start_period: 60s

volumes:
  pulsar_data:
  pulsar_conf:
  zookeeper_data:
  bookie_data:
