# ITT FastLane Full Docker Stack
# Deploy: docker compose up -d --build
# Stop:   docker compose down
# Wipe:   docker compose down -v

services:
  kafka1:
    image: apache/kafka:3.8.0
    container_name: btl-kafka1
    hostname: kafka1
    restart: unless-stopped
    ports:
      - "29092:29092"
    environment:
      KAFKA_NODE_ID: 1
      KAFKA_PROCESS_ROLES: broker,controller
      CLUSTER_ID: MkU3OEVBNTcwNTJENDM2Qk
      KAFKA_CONTROLLER_QUORUM_VOTERS: "1@kafka1:9093,2@kafka2:9093,3@kafka3:9093"
      KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: "CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT"
      KAFKA_LISTENERS: "PLAINTEXT://0.0.0.0:9092,CONTROLLER://0.0.0.0:9093,PLAINTEXT_HOST://0.0.0.0:29092"
      KAFKA_ADVERTISED_LISTENERS: "PLAINTEXT://kafka1:9092,PLAINTEXT_HOST://localhost:29092"
      KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT
      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 3
      KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 3
      KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 2
      KAFKA_MIN_INSYNC_REPLICAS: 2
      KAFKA_DEFAULT_REPLICATION_FACTOR: 3
      KAFKA_NUM_PARTITIONS: 3
      KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: 0
      KAFKA_AUTO_CREATE_TOPICS_ENABLE: "true"
      KAFKA_LOG_DIRS: /var/lib/kafka/data
    volumes:
      - kafka1_data:/var/lib/kafka/data
    healthcheck:
      test: ["CMD-SHELL", "/opt/kafka/bin/kafka-broker-api-versions.sh --bootstrap-server localhost:9092 >/dev/null 2>&1"]
      interval: 10s
      timeout: 5s
      retries: 12
      start_period: 30s

  kafka2:
    image: apache/kafka:3.8.0
    container_name: btl-kafka2
    hostname: kafka2
    restart: unless-stopped
    ports:
      - "29093:29092"
    environment:
      KAFKA_NODE_ID: 2
      KAFKA_PROCESS_ROLES: broker,controller
      CLUSTER_ID: MkU3OEVBNTcwNTJENDM2Qk
      KAFKA_CONTROLLER_QUORUM_VOTERS: "1@kafka1:9093,2@kafka2:9093,3@kafka3:9093"
      KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: "CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT"
      KAFKA_LISTENERS: "PLAINTEXT://0.0.0.0:9092,CONTROLLER://0.0.0.0:9093,PLAINTEXT_HOST://0.0.0.0:29092"
      KAFKA_ADVERTISED_LISTENERS: "PLAINTEXT://kafka2:9092,PLAINTEXT_HOST://localhost:29093"
      KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT
      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 3
      KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 3
      KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 2
      KAFKA_MIN_INSYNC_REPLICAS: 2
      KAFKA_DEFAULT_REPLICATION_FACTOR: 3
      KAFKA_NUM_PARTITIONS: 3
      KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: 0
      KAFKA_AUTO_CREATE_TOPICS_ENABLE: "true"
      KAFKA_LOG_DIRS: /var/lib/kafka/data
    volumes:
      - kafka2_data:/var/lib/kafka/data
    healthcheck:
      test: ["CMD-SHELL", "/opt/kafka/bin/kafka-broker-api-versions.sh --bootstrap-server localhost:9092 >/dev/null 2>&1"]
      interval: 10s
      timeout: 5s
      retries: 12
      start_period: 30s

  kafka3:
    image: apache/kafka:3.8.0
    container_name: btl-kafka3
    hostname: kafka3
    restart: unless-stopped
    ports:
      - "29094:29092"
    environment:
      KAFKA_NODE_ID: 3
      KAFKA_PROCESS_ROLES: broker,controller
      CLUSTER_ID: MkU3OEVBNTcwNTJENDM2Qk
      KAFKA_CONTROLLER_QUORUM_VOTERS: "1@kafka1:9093,2@kafka2:9093,3@kafka3:9093"
      KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: "CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT"
      KAFKA_LISTENERS: "PLAINTEXT://0.0.0.0:9092,CONTROLLER://0.0.0.0:9093,PLAINTEXT_HOST://0.0.0.0:29092"
      KAFKA_ADVERTISED_LISTENERS: "PLAINTEXT://kafka3:9092,PLAINTEXT_HOST://localhost:29094"
      KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT
      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 3
      KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 3
      KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 2
      KAFKA_MIN_INSYNC_REPLICAS: 2
      KAFKA_DEFAULT_REPLICATION_FACTOR: 3
      KAFKA_NUM_PARTITIONS: 3
      KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: 0
      KAFKA_AUTO_CREATE_TOPICS_ENABLE: "true"
      KAFKA_LOG_DIRS: /var/lib/kafka/data
    volumes:
      - kafka3_data:/var/lib/kafka/data
    healthcheck:
      test: ["CMD-SHELL", "/opt/kafka/bin/kafka-broker-api-versions.sh --bootstrap-server localhost:9092 >/dev/null 2>&1"]
      interval: 10s
      timeout: 5s
      retries: 12
      start_period: 30s

  topic-bootstrap:
    image: ittfastlane-app:latest
    build:
      context: .
      dockerfile: Dockerfile
    container_name: btl-topic-bootstrap
    restart: "no"
    depends_on:
      kafka1: {condition: service_healthy}
      kafka2: {condition: service_healthy}
      kafka3: {condition: service_healthy}
    env_file: [.env]
    environment:
      KAFKA_BOOTSTRAP_SERVERS: "kafka1:9092,kafka2:9092,kafka3:9092"
      PYTHONUNBUFFERED: "1"
    command: ["python", "scripts/bootstrap_topics.py"]

  api:
    image: ittfastlane-app:latest
    build: {context: ., dockerfile: Dockerfile}
    container_name: btl-api
    restart: unless-stopped
    depends_on:
      topic-bootstrap: {condition: service_completed_successfully}
    env_file: [.env]
    environment:
      KAFKA_BOOTSTRAP_SERVERS: "kafka1:9092,kafka2:9092,kafka3:9092"
      PYTHONUNBUFFERED: "1"
    ports:
      - "8080:8080"
    volumes:
      - app_logs:/app/logs
    command: ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8080", "--workers", "2"]

  lookup-minion:
    image: ittfastlane-app:latest
    build: {context: ., dockerfile: Dockerfile}
    container_name: btl-lookup-minion
    restart: unless-stopped
    depends_on:
      topic-bootstrap: {condition: service_completed_successfully}
    env_file: [.env]
    environment:
      KAFKA_BOOTSTRAP_SERVERS: "kafka1:9092,kafka2:9092,kafka3:9092"
      PYTHONUNBUFFERED: "1"
    volumes:
      - app_logs:/app/logs
    command: ["python", "-m", "minions.lookup_minion"]

  upsert-minion:
    image: ittfastlane-app:latest
    build: {context: ., dockerfile: Dockerfile}
    container_name: btl-upsert-minion
    restart: unless-stopped
    depends_on:
      topic-bootstrap: {condition: service_completed_successfully}
    env_file: [.env]
    environment:
      KAFKA_BOOTSTRAP_SERVERS: "kafka1:9092,kafka2:9092,kafka3:9092"
      PYTHONUNBUFFERED: "1"
    volumes:
      - app_logs:/app/logs
    command: ["python", "-m", "minions.upsert_minion"]

  file-upload-minion:
    image: ittfastlane-app:latest
    build: {context: ., dockerfile: Dockerfile}
    container_name: btl-file-upload-minion
    restart: unless-stopped
    depends_on:
      topic-bootstrap: {condition: service_completed_successfully}
    env_file: [.env]
    environment:
      KAFKA_BOOTSTRAP_SERVERS: "kafka1:9092,kafka2:9092,kafka3:9092"
      PYTHONUNBUFFERED: "1"
    volumes:
      - app_logs:/app/logs
    command: ["python", "-m", "minions.file_upload_minion"]

  commit-minion:
    image: ittfastlane-app:latest
    build: {context: ., dockerfile: Dockerfile}
    container_name: btl-commit-minion
    restart: unless-stopped
    depends_on:
      topic-bootstrap: {condition: service_completed_successfully}
    env_file: [.env]
    environment:
      KAFKA_BOOTSTRAP_SERVERS: "kafka1:9092,kafka2:9092,kafka3:9092"
      PYTHONUNBUFFERED: "1"
    volumes:
      - app_logs:/app/logs
    command: ["python", "-m", "minions.commit_minion"]

  status-listener:
    image: ittfastlane-app:latest
    build: {context: ., dockerfile: Dockerfile}
    container_name: btl-status-listener
    restart: unless-stopped
    depends_on:
      topic-bootstrap: {condition: service_completed_successfully}
    env_file: [.env]
    environment:
      KAFKA_BOOTSTRAP_SERVERS: "kafka1:9092,kafka2:9092,kafka3:9092"
      PYTHONUNBUFFERED: "1"
    volumes:
      - app_logs:/app/logs
    command: ["python", "-m", "minions.status_listener"]

volumes:
  app_logs:
  kafka1_data:
  kafka2_data:
  kafka3_data:

networks:
  default:
    name: ittfastlane-net
