# QCLM backend — self-hosted stack
#
#   curl -fsSLO https://qclm.iabdinur.dev/install/docker-compose.yml
#   docker compose up -d
#
# The desktop app connects to http://localhost:8080/api/v1 by default.
# Docs: https://qclm.iabdinur.dev/getting-started/backend/
#
# Optional settings (export them or put them in a .env file next to this one):
#   QCLM_VERSION   image tag to run              (default: latest)
#   QCLM_BIND      address the gateway listens on (default: 127.0.0.1 = this machine only;
#                  0.0.0.0 lets other machines on your network connect — see the docs first)
#   QCLM_PORT      gateway port on the host       (default: 8080)

name: qclm

x-service: &service
  restart: unless-stopped
  environment: &service-env
    SPRING_PROFILES_ACTIVE: dev
    JAVA_TOOL_OPTIONS: -XX:MaxRAMPercentage=25

services:
  postgres:
    image: postgres:17
    restart: unless-stopped
    environment:
      POSTGRES_DB: qclm
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
    volumes:
      - postgres-data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 5s
      timeout: 5s
      retries: 10

  kafka:
    image: confluentinc/cp-kafka:7.8.0
    restart: unless-stopped
    environment:
      KAFKA_NODE_ID: 1
      KAFKA_PROCESS_ROLES: broker,controller
      KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092,CONTROLLER://0.0.0.0:9093
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:9092
      KAFKA_CONTROLLER_QUORUM_VOTERS: 1@kafka:9093
      KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT
      KAFKA_LOG_DIRS: /var/lib/kafka/data
      CLUSTER_ID: qclm-local-cluster-01
      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
      KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1
      KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 1
      KAFKA_HEAP_OPTS: -Xms256m -Xmx512m
    volumes:
      - kafka-data:/var/lib/kafka/data
    healthcheck:
      test: ["CMD", "kafka-broker-api-versions", "--bootstrap-server", "localhost:9092"]
      interval: 10s
      timeout: 10s
      retries: 10

  metadata-service:
    <<: *service
    image: ghcr.io/iabdinur/qclmservices/qclm-metadata-service:${QCLM_VERSION:-latest}
    depends_on:
      postgres:
        condition: service_healthy

  data-service:
    <<: *service
    image: ghcr.io/iabdinur/qclmservices/qclm-data-service:${QCLM_VERSION:-latest}
    environment:
      <<: *service-env
      QCLM_STORAGE_TYPE: local
      QCLM_STORAGE_LOCALPATH: /data
    volumes:
      - qclm-data:/data

  acquisition-service:
    <<: *service
    image: ghcr.io/iabdinur/qclmservices/qclm-acquisition-service:${QCLM_VERSION:-latest}
    environment:
      <<: *service-env
      QCLM_HARDWARE_MODE: simulated
      QCLM_SERVICES_DATAURL: http://data-service:8082
    depends_on:
      kafka:
        condition: service_healthy

  processing-service:
    <<: *service
    image: ghcr.io/iabdinur/qclmservices/qclm-processing-service:${QCLM_VERSION:-latest}
    environment:
      <<: *service-env
      JAVA_TOOL_OPTIONS: -XX:MaxRAMPercentage=40
      QCLM_SERVICES_DATAURL: http://data-service:8082
    depends_on:
      kafka:
        condition: service_healthy

  inference-service:
    <<: *service
    image: ghcr.io/iabdinur/qclmservices/qclm-inference-service:${QCLM_VERSION:-latest}
    environment:
      <<: *service-env
      JAVA_TOOL_OPTIONS: -XX:MaxRAMPercentage=40
      QCLM_SERVICES_DATAURL: http://data-service:8082
    depends_on:
      kafka:
        condition: service_healthy

  experiment-service:
    <<: *service
    image: ghcr.io/iabdinur/qclmservices/qclm-experiment-service:${QCLM_VERSION:-latest}
    depends_on:
      kafka:
        condition: service_healthy
      metadata-service:
        condition: service_started
      acquisition-service:
        condition: service_started
      processing-service:
        condition: service_started
      inference-service:
        condition: service_started

  api-gateway:
    <<: *service
    image: ghcr.io/iabdinur/qclmservices/qclm-api-gateway:${QCLM_VERSION:-latest}
    environment:
      <<: *service-env
      SPRING_KAFKA_BOOTSTRAPSERVERS: kafka:9092
    ports:
      - "${QCLM_BIND:-127.0.0.1}:${QCLM_PORT:-8080}:8080"
    depends_on:
      kafka:
        condition: service_healthy
      metadata-service:
        condition: service_started
      data-service:
        condition: service_started
      acquisition-service:
        condition: service_started
      processing-service:
        condition: service_started
      inference-service:
        condition: service_started
      experiment-service:
        condition: service_started

volumes:
  postgres-data:
  kafka-data:
  qclm-data:
