# Copyright The OpenTelemetry Authors
# SPDX-License-Identifier: Apache-2.0

x-default-logging: &logging
  driver: "json-file"
  options:
    max-size: "5m"
    max-file: "2"
    tag: "{{.Name}}"

networks:
  default:
    name: opentelemetry-demo
    driver: bridge

services:
  # ********************
  # Telemetry Components
  # ********************
  # Jaeger
  jaeger:
    image: ${JAEGERTRACING_IMAGE}
    container_name: jaeger
    command:
      - "--memory.max-traces=5000"
      - "--query.base-path=/jaeger/ui"
      - "--prometheus.server-url=http://${PROMETHEUS_ADDR}"
      - "--prometheus.query.normalize-calls=true"
      - "--prometheus.query.normalize-duration=true"
    deploy:
      resources:
        limits:
          memory: 400M
    restart: unless-stopped
    ports:
      - "${JAEGER_SERVICE_PORT}"         # Jaeger UI
      - "${OTEL_COLLECTOR_PORT_GRPC}"
    environment:
      - METRICS_STORAGE_TYPE=prometheus
    logging: *logging

  # Grafana
  grafana:
    image: ${GRAFANA_IMAGE}
    container_name: grafana
    deploy:
      resources:
        limits:
          memory: 100M
    restart: unless-stopped
    environment:
      - "GF_INSTALL_PLUGINS=grafana-opensearch-datasource"
    volumes:
      - ./src/grafana/grafana.ini:/etc/grafana/grafana.ini
      - ./src/grafana/provisioning/:/etc/grafana/provisioning/
    ports:
      - "${GRAFANA_SERVICE_PORT}"
    logging: *logging

  # OpenTelemetry Collector
  otelcol:
    image: ${COLLECTOR_CONTRIB_IMAGE}
    container_name: otel-col
    deploy:
      resources:
        limits:
          memory: 200M
    restart: unless-stopped
    command: [ "--config=/etc/otelcol-config.yml", "--config=/etc/otelcol-config-extras.yml" ]
    volumes:
      - ./src/otelcollector/otelcol-config.yml:/etc/otelcol-config.yml
      - ./src/otelcollector/otelcol-config-extras.yml:/etc/otelcol-config-extras.yml
    ports:
      - "${OTEL_COLLECTOR_PORT_GRPC}"
      - "${OTEL_COLLECTOR_PORT_HTTP}"
    depends_on:
      - jaeger
    logging: *logging
    environment:
      - ENVOY_PORT

  # Prometheus
  prometheus:
    image: ${PROMETHEUS_IMAGE}
    container_name: prometheus
    command:
      - --web.console.templates=/etc/prometheus/consoles
      - --web.console.libraries=/etc/prometheus/console_libraries
      - --storage.tsdb.retention.time=1h
      - --config.file=/etc/prometheus/prometheus-config.yaml
      - --storage.tsdb.path=/prometheus
      - --web.enable-lifecycle
      - --web.route-prefix=/
      - --enable-feature=exemplar-storage
      - --enable-feature=otlp-write-receiver
    volumes:
      - ./src/prometheus/prometheus-config.yaml:/etc/prometheus/prometheus-config.yaml
    deploy:
      resources:
        limits:
          memory: 300M
    restart: unless-stopped
    ports:
      - "${PROMETHEUS_SERVICE_PORT}:${PROMETHEUS_SERVICE_PORT}"
    logging: *logging

  # OpenSearch
  opensearch:
    image: ${OPENSEARCH_IMAGE}
    container_name: opensearch
    deploy:
      resources:
        limits:
          memory: 1G
    restart: unless-stopped
    environment:
      - cluster.name=demo-cluster
      - node.name=demo-node
      - bootstrap.memory_lock=true
      - discovery.type=single-node
      - OPENSEARCH_JAVA_OPTS=-Xms300m -Xmx300m
      - DISABLE_INSTALL_DEMO_CONFIG=true
      - DISABLE_SECURITY_PLUGIN=true
    ulimits:
      memlock:
        soft: -1
        hard: -1
      nofile:
        soft: 65536
        hard: 65536
    ports:
      - "9200"
    logging: *logging

  # *****
  # Tests
  # *****
  # Frontend Tests
  frontendTests:
    image: ${IMAGE_NAME}:${DEMO_VERSION}-frontend-tests
    container_name: frontend-tests
    build:
      context: ./
      dockerfile: ./src/frontend/Dockerfile.cypress
    profiles:
      - tests
    volumes:
      - ./src/frontend/cypress/videos:/app/cypress/videos
      - ./src/frontend/cypress/screenshots:/app/cypress/screenshots
    environment:
      - CYPRESS_baseUrl=http://${FRONTEND_ADDR}
      - FRONTEND_ADDR
      - NODE_ENV=production
    depends_on:
      - frontend

  # Tracebased Tests
  traceBasedTests:
    image: ${IMAGE_NAME}:${DEMO_VERSION}-traceBasedTests
    container_name: traceBasedTests
    profiles:
      - tests
    build:
      context: ./
      dockerfile: ./test/tracetesting/Dockerfile
    environment:
      - AD_SERVICE_ADDR
      - CART_SERVICE_ADDR
      - CHECKOUT_SERVICE_ADDR
      - CURRENCY_SERVICE_ADDR
      - EMAIL_SERVICE_ADDR
      - FRONTEND_ADDR
      - PAYMENT_SERVICE_ADDR
      - PRODUCT_CATALOG_SERVICE_ADDR
      - RECOMMENDATION_SERVICE_ADDR
      - SHIPPING_SERVICE_ADDR
      - KAFKA_SERVICE_ADDR
    extra_hosts:
      - "host.docker.internal:host-gateway"
    volumes:
      - ./test/tracetesting:/app/test/tracetesting
      - ./pb:/app/pb
    depends_on:
      tracetest-server:
        condition: service_healthy
      # adding demo services as dependencies
      frontend:
        condition: service_started
      adservice:
        condition: service_started
      cartservice:
        condition: service_started
      checkoutservice:
        condition: service_started
      currencyservice:
        condition: service_started
      emailservice:
        condition: service_started
      paymentservice:
        condition: service_started
      productcatalogservice:
        condition: service_started
      recommendationservice:
        condition: service_started
      shippingservice:
        condition: service_started
      quoteservice:
        condition: service_started
      accountingservice:
        condition: service_started
      frauddetectionservice:
        condition: service_started
      flagd:
        condition: service_started

  tracetest-server:
    image: ${TRACETEST_IMAGE}
    platform: linux/amd64
    container_name: tracetest-server
    profiles:
      - tests
      - odd          # Observabilty-Driven Development (ODD)
    volumes:
      - type: bind
        source: ./test/tracetesting/tracetest-config.yaml
        target: /app/tracetest.yaml
      - type: bind
        source: ./test/tracetesting/tracetest-provision.yaml
        target: /app/provision.yaml
    command: --provisioning-file /app/provision.yaml
    ports:
      - 11633:11633
    extra_hosts:
      - "host.docker.internal:host-gateway"
    depends_on:
      tracetest-postgres:
        condition: service_healthy
      otelcol:
        condition: service_started
    healthcheck:
      test: [ "CMD", "wget", "--spider", "localhost:11633" ]
      interval: 1s
      timeout: 3s
      retries: 60

  tracetest-postgres:
    image: ${POSTGRES_IMAGE}
    container_name: tracetest-postgres
    profiles:
      - tests
      - odd          # Observabilty-Driven Development (ODD)
    environment:
      POSTGRES_PASSWORD: postgres
      POSTGRES_USER: postgres
    healthcheck:
      test: pg_isready -U "$$POSTGRES_USER" -d "$$POSTGRES_DB"
      interval: 1s
      timeout: 5s
      retries: 60
    ports:
      - 5432
