# REMSFAL - Getting Started Docker Compose
#
# Startet das komplette REMSFAL-Projekt (Frontend + alle Backend-Microservices)
# inklusive aller benötigten Datenbanken und Kafka ausschließlich auf Basis von
# fertigen Container-Images aus der GitHub Container Registry (ghcr.io).
# Es wird kein lokaler Build benötigt.
#
# Voraussetzung: Die Datei nginx.conf muss im selben Verzeichnis liegen wie
# diese docker-compose.yml.
#
# Verwendung:
#   docker compose up -d
#
# Anschließend ist die Anwendung unter http://localhost:8090 erreichbar.
#
# Weitere Informationen: https://remsfal.de/getting-started/docker-setup

services:
  # ---------------------------------------------------------------------
  # Datenbanken
  # ---------------------------------------------------------------------
  postgres:
    image: postgres:16
    container_name: remsfal-postgres
    restart: unless-stopped
    environment:
      POSTGRES_DB: REMSFAL
      POSTGRES_USER: remsfalAdmin
      POSTGRES_PASSWORD: remsfalSecret
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: [ "CMD-SHELL", "pg_isready -U remsfalAdmin -d REMSFAL" ]
      interval: 10s
      timeout: 5s
      retries: 10
    networks:
      - remsfal

  cassandra:
    image: cassandra:5
    container_name: remsfal-cassandra
    restart: unless-stopped
    environment:
      CASSANDRA_CLUSTER_NAME: remsfal-cassandra-cluster
      CASSANDRA_NUM_TOKENS: 8
      CASSANDRA_SEEDS: cassandra
      CASSANDRA_USER: remsfalAdmin
      CASSANDRA_PASSWORD: remsfalSecret
      MAX_HEAP_SIZE: 1G
      HEAP_NEWSIZE: 256M
    mem_limit: 3g
    memswap_limit: 4g
    healthcheck:
      test: [ "CMD-SHELL", "cqlsh -e 'describe cluster'" ]
      interval: 10s
      timeout: 5s
      retries: 10
      start_period: 60s
    volumes:
      - cassandra_data:/var/lib/cassandra
    networks:
      - remsfal

  minio:
    image: minio/minio
    container_name: remsfal-minio
    restart: unless-stopped
    environment:
      MINIO_ROOT_USER: remsfalAdmin
      MINIO_ROOT_PASSWORD: remsfalSecret
    command: server /data --console-address ":9001"
    volumes:
      - minio_data:/data
    healthcheck:
      test: [ "CMD", "curl", "-f", "http://localhost:9000/minio/health/live" ]
      interval: 10s
      timeout: 5s
      retries: 10
    networks:
      - remsfal

  # ---------------------------------------------------------------------
  # Event Streaming
  # ---------------------------------------------------------------------
  kafka-broker:
    image: apache/kafka:latest
    hostname: kafka-broker
    container_name: remsfal-kafka-broker
    restart: unless-stopped
    environment:
      KAFKA_NODE_ID: 1
      KAFKA_PROCESS_ROLES: broker,controller
      KAFKA_LISTENERS: INTERNAL://0.0.0.0:29092,EXTERNAL://0.0.0.0:9092,CONTROLLER://0.0.0.0:9093
      KAFKA_ADVERTISED_LISTENERS: INTERNAL://kafka-broker:29092,EXTERNAL://kafka-broker:9092
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: INTERNAL:PLAINTEXT,EXTERNAL:PLAINTEXT,CONTROLLER:PLAINTEXT
      KAFKA_INTER_BROKER_LISTENER_NAME: INTERNAL
      KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
      KAFKA_CONTROLLER_QUORUM_VOTERS: 1@kafka-broker:9093
      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
      KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1
      KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 1
      KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: 0
      KAFKA_NUM_PARTITIONS: 3
    healthcheck:
      test: [ "CMD", "bash", "-c", "nc -z localhost 29092" ]
      interval: 10s
      timeout: 5s
      retries: 10
    networks:
      - remsfal

  # ---------------------------------------------------------------------
  # Backend Microservices (ghcr.io/remsfal/*)
  # ---------------------------------------------------------------------
  remsfal-platform:
    image: ghcr.io/remsfal/remsfal-platform:latest
    container_name: remsfal-platform
    restart: unless-stopped
    depends_on:
      postgres:
        condition: service_healthy
      kafka-broker:
        condition: service_healthy
    environment:
      QUARKUS_DATASOURCE_USERNAME: remsfalAdmin
      QUARKUS_DATASOURCE_PASSWORD: remsfalSecret
      QUARKUS_DATASOURCE_JDBC_URL: jdbc:postgresql://postgres:5432/REMSFAL
      MP_MESSAGING_CONNECTOR_SMALLRYE_KAFKA_BOOTSTRAP_SERVERS: kafka-broker:9092
      # Muss auf die von außen erreichbare Adresse des Reverse Proxys zeigen,
      # da sie für OAuth-Redirects und Links in E-Mails verwendet wird.
      DE_REMSFAL_FRONTEND_URL_BASE: http://localhost:8090
    ports:
      - "8080:8080"
    networks:
      - remsfal

  remsfal-ticketing:
    image: ghcr.io/remsfal/remsfal-ticketing:latest
    container_name: remsfal-ticketing
    restart: unless-stopped
    depends_on:
      cassandra:
        condition: service_healthy
      minio:
        condition: service_healthy
      kafka-broker:
        condition: service_healthy
      remsfal-platform:
        condition: service_started
    environment:
      QUARKUS_CASSANDRA_CONTACT_POINTS: cassandra:9042
      QUARKUS_CASSANDRA_AUTH_USERNAME: remsfalAdmin
      QUARKUS_CASSANDRA_AUTH_PASSWORD: remsfalSecret
      QUARKUS_CASSANDRA_LOCAL_DATACENTER: datacenter1
      QUARKUS_MINIO_HOST: http://minio
      QUARKUS_MINIO_PORT: 9000
      QUARKUS_MINIO_ACCESS_KEY: remsfalAdmin
      QUARKUS_MINIO_SECRET_KEY: remsfalSecret
      QUARKUS_MINIO_SECURE: "false"
      MP_MESSAGING_CONNECTOR_SMALLRYE_KAFKA_BOOTSTRAP_SERVERS: kafka-broker:9092
      # Die Platform-Microservice stellt die öffentlichen Schlüssel zur
      # Prüfung der JWT-Zugriffstoken bereit.
      MP_JWT_VERIFY_PUBLICKEY_LOCATION: http://remsfal-platform:8080/api/v1/authentication/jwks
    ports:
      - "8081:8081"
    networks:
      - remsfal

  remsfal-notification:
    image: ghcr.io/remsfal/remsfal-notification:latest
    container_name: remsfal-notification
    restart: unless-stopped
    depends_on:
      kafka-broker:
        condition: service_healthy
    environment:
      MP_MESSAGING_CONNECTOR_SMALLRYE_KAFKA_BOOTSTRAP_SERVERS: kafka-broker:9092
      # Ohne eigenen SMTP-Server werden E-Mails nur geloggt statt versendet.
      QUARKUS_MAILER_MOCK: "true"
      QUARKUS_MAILER_FROM: no-reply@example.com
    ports:
      - "8082:8082"
    networks:
      - remsfal

  # ---------------------------------------------------------------------
  # Frontend
  # ---------------------------------------------------------------------
  remsfal-frontend:
    image: ghcr.io/remsfal/remsfal-frontend:latest
    container_name: remsfal-frontend
    restart: unless-stopped
    networks:
      - remsfal

  # ---------------------------------------------------------------------
  # Reverse Proxy
  #
  # Das Frontend-Image enthält nur die statischen Dateien der SPA und
  # spricht die Backend-Microservices über relative Pfade (/api, /ticketing,
  # /notification) an. Dieser Reverse Proxy bündelt Frontend und Backend
  # unter einem gemeinsamen Origin, so wie es der Vite-Dev-Server auch in
  # der lokalen Entwicklung tut (siehe vite.config.ts im remsfal-frontend
  # Repository).
  # ---------------------------------------------------------------------
  reverse-proxy:
    image: nginx:stable
    container_name: remsfal-reverse-proxy
    restart: unless-stopped
    depends_on:
      - remsfal-frontend
      - remsfal-platform
      - remsfal-ticketing
      - remsfal-notification
    volumes:
      - ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
    ports:
      - "8090:80"
    networks:
      - remsfal

networks:
  remsfal:
    driver: bridge

volumes:
  postgres_data:
  cassandra_data:
  minio_data:
