name : ${PLATFORM_NAME:-kodeuni-platform}
services:
  app:
    image: http://localhost:5000/kodeuni-platform:1.0.2
    ports:
      - 8081:8080
    env_file:
      - ../../appenvs/.dev.env
    environment:
      - PORT=${PORT:-8080}
      - DB_DSN=${DB_DSN:-host=postgres user=postgres password=secret dbname=kodeuni-platform port=5432 sslmode=disable}
      - ADMIN_USERNAME=${ADMIN_USERNAME:-paul@duxte.com}
      - ADMIN_PASSWORD=${ADMIN_PASSWORD:-987654321}
      - API_BASE_URL=${API_BASE_URL:-http://localhost:8080/api}
      - APP_URL=${APP_URL:-http://localhost:8080/frontend}
      - API_PORT=${API_PORT:-8080}
      - JWT_SECRET=${JWT_SECRET:-your-secret-key}
      - REDIS_ADDR=${REDIS_ADDR:-redis:6379}
      - REDIS_PASSWORD=${REDIS_PASSWORD:-}
      - KAFKA_BROKERS=${KAFKA_BROKERS:-kafka:9092}
      - KAFKA_TOPIC=${KAFKA_TOPIC:-events}
      - KAFKA_GROUP_ID=${KAFKA_GROUP_ID:-kodeuni-platform-group}
      - ELASTICSEARCH_URL=${ELASTICSEARCH_URL:-http://elasticsearch:9200}
      - ELASTICSEARCH_INDEX=${ELASTICSEARCH_INDEX:-content}
      - MINIO_ENDPOINT=${MINIO_ENDPOINT:-minio:9000}
      - MINIO_ACCESS_KEY=${MINIO_ACCESS_KEY:-minioadmin}
      - MINIO_SECRET_KEY=${MINIO_SECRET_KEY:-minioadmin123}
      - MINIO_BUCKET_NAME=${MINIO_BUCKET_NAME:-my-bucket}
      - MINIO_USE_SSL=${MINIO_USE_SSL:-false}
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_healthy
      kafka:
        condition: service_healthy
      elasticsearch:
        condition: service_healthy
      minio:
        condition: service_healthy
      wazuh:
        condition: service_healthy
    volumes:
      - ./static:/app/static
      - ./docker/scripts/databases/wait-for-postgres.sh:/app/scripts/databases/wait-for-postgres.sh:ro

    command:
      - ./scripts/wait-for-postgres.sh
      - ./app
    networks:
      - app-network
    restart: unless-stopped

  postgres:
    image: postgres:15-alpine
    environment:
      - POSTGRES_USER=${POSTGRES_USER:-postgres}
      - POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-secret}
      - POSTGRES_DB=${POSTGRES_DB:-kodeuni-platform}
      - POSTGRES_MULTIPLE_USERS=${KONG_PG_USER:-kong}
      - POSTGRES_MULTIPLE_PASSWORDS=${KONG_PG_PASSWORD:-secret}
      - POSTGRES_MULTIPLE_DATABASES=${KONG_PG_DATABASE:-kong}
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-postgres}"]
      interval: 5s
      timeout: 5s
      retries: 5
    networks:
      - app-network
    restart: unless-stopped

  redis:
    image: redis:latest
    environment:
      - REDIS_PASSWORD=${REDIS_PASSWORD:-}
    command: >
      sh -c "if [ -z \"$REDIS_PASSWORD\" ]; then redis-server /usr/local/etc/redis/redis.conf; else redis-server /usr/local/etc/redis/redis.conf --requirepass \"$REDIS_PASSWORD\"; fi"
    volumes:
      - redis_data:/data
      - ./redis-config/redis.conf:/usr/local/etc/redis/redis.conf
    healthcheck:
      test: ["CMD-SHELL", "if [ -z \"$REDIS_PASSWORD\" ]; then redis-cli ping | grep PONG || exit 1; else redis-cli -a \"$REDIS_PASSWORD\" ping | grep PONG || exit 1; fi"]
      interval: 10s
      timeout: 10s
      retries: 5
      start_period: 30s
    networks:
      - app-network
    restart: unless-stopped

  zookeeper:
    image: bitnami/zookeeper:latest
    environment:
      - ALLOW_ANONYMOUS_LOGIN=yes
    volumes:
      - zookeeper_data:/bitnami/zookeeper
      - zookeeper_logs:/opt/bitnami/zookeeper/logs
    healthcheck:
      test: ["CMD-SHELL", "echo ruok | nc localhost 2181 | grep imok || exit 1"]
      interval: 10s
      timeout: 5s
      retries: 3
      start_period: 10s
    networks:
      - app-network
    restart: unless-stopped

  kafka:
    image: bitnami/kafka:latest
    environment:
      - KAFKA_BROKER_ID=1
      - KAFKA_CFG_NODE_ID=1
      - KAFKA_CFG_PROCESS_ROLES=broker,controller
      - KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=PLAINTEXT:PLAINTEXT,CONTROLLER:PLAINTEXT
      - KAFKA_CFG_LISTENERS=PLAINTEXT://0.0.0.0:9092,CONTROLLER://0.0.0.0:9093
      - KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://kafka:9092
      - KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181
      - ALLOW_PLAINTEXT_LISTENER=yes
      - KAFKA_CFG_CONTROLLER_QUORUM_VOTERS=1@localhost:9093
      - KAFKA_CFG_CONTROLLER_LISTENER_NAMES=CONTROLLER
    volumes:
      - kafka_data:/bitnami/kafka
      - kafka_logs:/opt/bitnami/kafka/logs
    healthcheck:
      test: ["CMD-SHELL", "kafka-topics.sh --bootstrap-server localhost:9092 --list"]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 30s
    networks:
      - app-network
    depends_on:
      - zookeeper
    restart: unless-stopped

  wazuh:
    image: wazuh/wazuh-manager:4.9.0
    volumes:
      - wazuh-data:/var/ossec/data
    environment:
      - WAZUH_SERVER_PORT=1515
      - WAZUH_LOG_LEVEL=info
    healthcheck:
      test: ["CMD-SHELL", "curl -s -f http://localhost:55000 || exit 1"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 60s
    networks:
      - app-network
    restart: unless-stopped

  wazuh-indexer:
    image: wazuh/wazuh-indexer:4.9.0
    environment:
      - opensearch.network.host=0.0.0.0
      - discovery.type=single-node
    healthcheck:
      test: ["CMD-SHELL", "curl -s -f http://localhost:9200/_cat/health?h=status"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 60s
    networks:
      - app-network
    restart: unless-stopped

  wazuh-dashboard:
    image: wazuh/wazuh-dashboard:4.9.0
    ports:
      - 5601:5601
    environment:
      - WAZUH_API_URL=http://wazuh:55000
      - OPENSEARCH_HOSTS=http://wazuh-indexer:9200
    depends_on:
      - wazuh
      - wazuh-indexer
    networks:
      - app-network
    restart: unless-stopped

  elasticsearch:
    image: elasticsearch:8.15.3
    environment:
      - discovery.type=single-node
      - ES_JAVA_OPTS=-Xms512m -Xmx512m
      - xpack.security.enabled=false
    volumes:
      - elasticsearch_data:/usr/share/elasticsearch/data
    healthcheck:
      test: ["CMD-SHELL", "curl -s -f http://localhost:9200/_cat/health?h=status"]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 30s
    networks:
      - app-network
    restart: unless-stopped

  minio:
    image: minio/minio:latest
    environment:
      - MINIO_ROOT_USER=${MINIO_ACCESS_KEY:-minioadmin}
      - MINIO_ROOT_PASSWORD=${MINIO_SECRET_KEY:-minioadmin123}
    command: server /data --console-address ":9001"
    volumes:
      - minio_data:/data
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
      interval: 30s
      timeout: 10s
      retries: 3
    networks:
      - app-network
    restart: unless-stopped

  mongodb:
    image: mongo:6.0
    environment:
      - MONGO_INITDB_ROOT_USERNAME=${MONGODB_USERNAME:-mongo}
      - MONGO_INITDB_ROOT_PASSWORD=${MONGODB_PASSWORD:-mongo}
      - MONGO_INITDB_DATABASE=${MONGODB_DATABASE:-kodeuni-platform}
    volumes:
      - mongodb_data:/data/db
    healthcheck:
      test: ["CMD-SHELL", "mongosh --eval 'db.runCommand(\"ping\").ok' --quiet || exit 1"]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 10s
    networks:
      - app-network
    restart: unless-stopped

  prometheus:
    image: prom/prometheus:latest
    volumes:
      - ./observability/prometheus.yml:/etc/prometheus/prometheus.yml
      - prometheus_data:/prometheus
    command:
      - --config.file=/etc/prometheus/prometheus.yml
      - --storage.tsdb.path=/prometheus
    healthcheck:
      test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:9090/-/healthy"]
      interval: 10s
      timeout: 5s
      retries: 3
      start_period: 10s
    networks:
      - app-network
    restart: unless-stopped

  grafana:
    image: grafana/grafana:latest
    volumes:
      - grafana_data:/var/lib/grafana
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/api/health"]
      interval: 10s
      timeout: 5s
      retries: 3
      start_period: 10s
    networks:
      - app-network
    restart: unless-stopped

  postgres_exporter:
    image: prometheuscommunity/postgres-exporter:latest
    environment:
      - DATA_SOURCE_NAME=postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:-secret}@postgres:5432/${POSTGRES_DB:-kodeuni-platform}?sslmode=disable
    depends_on:
      postgres:
        condition: service_healthy
    networks:
      - app-network
    restart: unless-stopped

  kong:
    image: kong:3.9.1-ubuntu
    environment:
      - KONG_DATABASE=${KONG_PG_DATABASE:-kong}
      - KONG_PG_HOST=${KONG_PG_HOST:-postgres}
      - KONG_PG_USER=${KONG_PG_USER:-kong}
      - KONG_PG_PASSWORD=${KONG_PG_PASSWORD:-secret}
      - KONG_PG_DATABASE=${KONG_PG_DATABASE:-kong}
      - KONG_PROXY_ACCESS_LOG=/dev/stdout
      - KONG_ADMIN_ACCESS_LOG=/dev/stdout
      - KONG_PROXY_ERROR_LOG=/dev/stderr
      - KONG_ADMIN_ERROR_LOG=/dev/stderr
      - KONG_PROXY_LISTEN=0.0.0.0:8000
      - KONG_ADMIN_LISTEN=0.0.0.0:8001
      - KONG_ADMIN_API_URI=http://kong:8001
    ports:
      - 8000:8000
      - 8443:8443
      - 8001:8001
      - 8444:8444
    volumes:
      - kong_data:/kong
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8001/status"]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 30s
    depends_on:
      postgres:
        condition: service_healthy
      kong-migrations:
        condition: service_completed_successfully
    networks:
      - app-network
    restart: unless-stopped

  kong-migrations:
    image: kong:3.9.1-ubuntu
    depends_on:
      postgres:
        condition: service_healthy
    environment:
      - KONG_DATABASE=postgres
      - KONG_PG_HOST=postgres
      - KONG_PG_USER=${KONG_PG_USER:-kong}
      - KONG_PG_PASSWORD=${KONG_PG_PASSWORD:-secret}
      - KONG_PG_DATABASE=${KONG_PG_DATABASE:-kong}
    command: kong migrations bootstrap
    networks:
      - app-network
    restart: no

volumes:
  postgres_data:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: ${PWD}/data/postgres_data
  redis_data:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: ${PWD}/data/redis_data
  zookeeper_data:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: ${PWD}/data/zookeeper_data
  zookeeper_logs:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: ${PWD}/data/zookeeper_logs
  kafka_data:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: ${PWD}/data/kafka_data
  kafka_logs:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: ${PWD}/data/kafka_logs
  kong_data:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: ${PWD}/data/kong_data
  elasticsearch_data:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: ${PWD}/data/elasticsearch_data
  prometheus_data:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: ${PWD}/data/prometheus_data
  grafana_data:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: ${PWD}/data/grafana_data
  minio_data:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: ${PWD}/data/minio_data
  mongodb_data:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: ${PWD}/data/mongodb_data
  wazuh-data:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: ${PWD}/data/wazuh_data

networks:
  app-network:
    driver: bridge
