# 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: # ****************** # Core Demo Services # ****************** # AdService ad: image: ${IMAGE_NAME}:${DEMO_VERSION}-ad container_name: ad build: context: ./ dockerfile: ${AD_DOCKERFILE} cache_from: - ${IMAGE_NAME}:${IMAGE_VERSION}-ad args: OTEL_JAVA_AGENT_VERSION: ${OTEL_JAVA_AGENT_VERSION} deploy: resources: limits: memory: 300M restart: unless-stopped ports: - "${AD_PORT}" environment: - AD_PORT - FLAGD_HOST - FLAGD_PORT - OTEL_EXPORTER_OTLP_ENDPOINT=http://${OTEL_COLLECTOR_HOST}:${OTEL_COLLECTOR_PORT_HTTP} - OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE - OTEL_RESOURCE_ATTRIBUTES - OTEL_LOGS_EXPORTER=otlp - OTEL_SERVICE_NAME=ad # Workaround on OSX for https://bugs.openjdk.org/browse/JDK-8345296 - _JAVA_OPTIONS depends_on: otel-collector: condition: service_started logging: *logging # Cart service cart: image: ${IMAGE_NAME}:${DEMO_VERSION}-cart container_name: cart build: context: ./ dockerfile: ${CART_DOCKERFILE} cache_from: - ${IMAGE_NAME}:${IMAGE_VERSION}-cart deploy: resources: limits: memory: 160M restart: unless-stopped ports: - "${CART_PORT}" environment: - CART_PORT - FLAGD_HOST - FLAGD_PORT - VALKEY_ADDR - OTEL_EXPORTER_OTLP_ENDPOINT - OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE - OTEL_RESOURCE_ATTRIBUTES - OTEL_SERVICE_NAME=cart - ASPNETCORE_URLS=http://*:${CART_PORT} depends_on: valkey-cart: condition: service_started otel-collector: condition: service_started logging: *logging # Checkout service checkout: image: ${IMAGE_NAME}:${DEMO_VERSION}-checkout container_name: checkout build: context: ./ dockerfile: ${CHECKOUT_DOCKERFILE} cache_from: - ${IMAGE_NAME}:${IMAGE_VERSION}-checkout deploy: resources: limits: memory: 20M restart: unless-stopped ports: - "${CHECKOUT_PORT}" environment: - CHECKOUT_PORT - CART_ADDR - CURRENCY_ADDR - EMAIL_ADDR - FLAGD_HOST - FLAGD_PORT - PAYMENT_ADDR - PRODUCT_CATALOG_ADDR - SHIPPING_ADDR - GOMEMLIMIT=16MiB - OTEL_EXPORTER_OTLP_ENDPOINT - OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE - OTEL_RESOURCE_ATTRIBUTES - OTEL_SERVICE_NAME=checkout depends_on: cart: condition: service_started currency: condition: service_started email: condition: service_started payment: condition: service_started product-catalog: condition: service_started shipping: condition: service_started otel-collector: condition: service_started logging: *logging # Currency service currency: image: ${IMAGE_NAME}:${DEMO_VERSION}-currency container_name: currency build: context: ./ dockerfile: ${CURRENCY_DOCKERFILE} cache_from: - ${IMAGE_NAME}:${IMAGE_VERSION}-currency args: OPENTELEMETRY_CPP_VERSION: ${OPENTELEMETRY_CPP_VERSION} deploy: resources: limits: memory: 20M restart: unless-stopped ports: - "${CURRENCY_PORT}" environment: - CURRENCY_PORT - VERSION=${IMAGE_VERSION} - OTEL_EXPORTER_OTLP_ENDPOINT - OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE - OTEL_RESOURCE_ATTRIBUTES - OTEL_SERVICE_NAME=currency depends_on: otel-collector: condition: service_started logging: *logging # Email service email: image: ${IMAGE_NAME}:${DEMO_VERSION}-email container_name: email build: context: ./src/email cache_from: - ${IMAGE_NAME}:${IMAGE_VERSION}-email deploy: resources: limits: memory: 100M restart: unless-stopped ports: - "${EMAIL_PORT}" environment: - APP_ENV=production - EMAIL_PORT - FLAGD_HOST - FLAGD_PORT - OTEL_EXPORTER_OTLP_ENDPOINT=http://${OTEL_COLLECTOR_HOST}:${OTEL_COLLECTOR_PORT_HTTP} - OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE - OTEL_RESOURCE_ATTRIBUTES - OTEL_SERVICE_NAME=email depends_on: otel-collector: condition: service_started logging: *logging # Frontend frontend: image: ${IMAGE_NAME}:${DEMO_VERSION}-frontend container_name: frontend build: context: ./ dockerfile: ${FRONTEND_DOCKERFILE} cache_from: - ${IMAGE_NAME}:${IMAGE_VERSION}-frontend deploy: resources: limits: memory: 250M restart: unless-stopped ports: - "${FRONTEND_PORT}" environment: - PORT=${FRONTEND_PORT} - FRONTEND_ADDR - AD_ADDR - CART_ADDR - CHECKOUT_ADDR - CURRENCY_ADDR - PRODUCT_CATALOG_ADDR - RECOMMENDATION_ADDR - SHIPPING_ADDR - OTEL_EXPORTER_OTLP_ENDPOINT - OTEL_RESOURCE_ATTRIBUTES - ENV_PLATFORM - OTEL_SERVICE_NAME=frontend - PUBLIC_OTEL_EXPORTER_OTLP_TRACES_ENDPOINT - OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE - WEB_OTEL_SERVICE_NAME=frontend-web - OTEL_COLLECTOR_HOST - FLAGD_HOST - FLAGD_PORT depends_on: ad: condition: service_started cart: condition: service_started checkout: condition: service_started currency: condition: service_started product-catalog: condition: service_started quote: condition: service_started recommendation: condition: service_started shipping: condition: service_started otel-collector: condition: service_started image-provider: condition: service_started logging: *logging # Frontend Proxy (Envoy) frontend-proxy: image: ${IMAGE_NAME}:${DEMO_VERSION}-frontend-proxy container_name: frontend-proxy build: context: ./ dockerfile: ${FRONTEND_PROXY_DOCKERFILE} deploy: resources: limits: memory: 65M restart: unless-stopped ports: - "${ENVOY_PORT}:${ENVOY_PORT}" - "${ENVOY_ADMIN_PORT}:${ENVOY_ADMIN_PORT}" environment: - FRONTEND_PORT - FRONTEND_HOST - LOCUST_WEB_HOST - LOCUST_WEB_PORT - GRAFANA_PORT - GRAFANA_HOST - JAEGER_UI_PORT - JAEGER_HOST - OTEL_COLLECTOR_HOST - IMAGE_PROVIDER_HOST - IMAGE_PROVIDER_PORT - OTEL_COLLECTOR_PORT_GRPC - OTEL_COLLECTOR_PORT_HTTP - OTEL_RESOURCE_ATTRIBUTES - OTEL_SERVICE_NAME=frontend-proxy - ENVOY_PORT - ENVOY_ADMIN_PORT - FLAGD_HOST - FLAGD_PORT - FLAGD_UI_HOST - FLAGD_UI_PORT depends_on: frontend: condition: service_started load-generator: condition: service_started jaeger: condition: service_started grafana: condition: service_started dns_search: "" # image-provider image-provider: image: ${IMAGE_NAME}:${DEMO_VERSION}-image-provider container_name: image-provider build: context: ./ dockerfile: ${IMAGE_PROVIDER_DOCKERFILE} cache_from: - ${IMAGE_NAME}:${IMAGE_VERSION}-image-provider deploy: resources: limits: memory: 120M restart: unless-stopped ports: - "${IMAGE_PROVIDER_PORT}" environment: - IMAGE_PROVIDER_PORT - OTEL_COLLECTOR_HOST - OTEL_COLLECTOR_PORT_GRPC - OTEL_RESOURCE_ATTRIBUTES - OTEL_SERVICE_NAME=image-provider depends_on: otel-collector: condition: service_started logging: *logging # Load Generator load-generator: image: ${IMAGE_NAME}:${DEMO_VERSION}-load-generator container_name: load-generator build: context: ./ dockerfile: ${LOAD_GENERATOR_DOCKERFILE} cache_from: - ${IMAGE_NAME}:${IMAGE_VERSION}-load-generator deploy: resources: limits: memory: 120M restart: unless-stopped ports: - "${LOCUST_WEB_PORT}" environment: - LOCUST_WEB_PORT - LOCUST_USERS - LOCUST_HOST - LOCUST_HEADLESS - LOCUST_AUTOSTART - LOCUST_BROWSER_TRAFFIC_ENABLED=false - OTEL_EXPORTER_OTLP_ENDPOINT - OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE - OTEL_RESOURCE_ATTRIBUTES - OTEL_SERVICE_NAME=load-generator - PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python - LOCUST_WEB_HOST=0.0.0.0 - FLAGD_HOST - FLAGD_PORT - FLAGD_OFREP_PORT depends_on: frontend: condition: service_started flagd: condition: service_started logging: *logging # Payment service payment: image: ${IMAGE_NAME}:${DEMO_VERSION}-payment container_name: payment build: context: ./ dockerfile: ${PAYMENT_DOCKERFILE} cache_from: - ${IMAGE_NAME}:${IMAGE_VERSION}-payment deploy: resources: limits: memory: 120M restart: unless-stopped ports: - "${PAYMENT_PORT}" environment: - FLAGD_HOST - FLAGD_PORT - PAYMENT_PORT - OTEL_EXPORTER_OTLP_ENDPOINT - OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE - OTEL_RESOURCE_ATTRIBUTES - OTEL_SERVICE_NAME=payment depends_on: otel-collector: condition: service_started logging: *logging # Product Catalog service product-catalog: image: ${IMAGE_NAME}:${DEMO_VERSION}-product-catalog container_name: product-catalog build: context: ./ dockerfile: ${PRODUCT_CATALOG_DOCKERFILE} cache_from: - ${IMAGE_NAME}:${IMAGE_VERSION}-product-catalog deploy: resources: limits: memory: 20M restart: unless-stopped ports: - "${PRODUCT_CATALOG_PORT}" environment: - FLAGD_HOST - FLAGD_PORT - PRODUCT_CATALOG_PORT - PRODUCT_CATALOG_RELOAD_INTERVAL - GOMEMLIMIT=16MiB - OTEL_EXPORTER_OTLP_ENDPOINT - OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE - OTEL_RESOURCE_ATTRIBUTES - OTEL_SERVICE_NAME=product-catalog volumes: - ./src/product-catalog/products:/usr/src/app/products depends_on: otel-collector: condition: service_started logging: *logging # Quote service quote: image: ${IMAGE_NAME}:${DEMO_VERSION}-quote container_name: quote build: context: ./ dockerfile: ${QUOTE_DOCKERFILE} cache_from: - ${IMAGE_NAME}:${IMAGE_VERSION}-quote deploy: resources: limits: memory: 40M restart: unless-stopped ports: - "${QUOTE_PORT}" environment: - OTEL_EXPORTER_OTLP_ENDPOINT=http://${OTEL_COLLECTOR_HOST}:${OTEL_COLLECTOR_PORT_HTTP} - OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE - OTEL_PHP_AUTOLOAD_ENABLED=true - QUOTE_PORT - OTEL_PHP_INTERNAL_METRICS_ENABLED=true - OTEL_RESOURCE_ATTRIBUTES - OTEL_SERVICE_NAME=quote depends_on: otel-collector: condition: service_started logging: *logging # Recommendation service recommendation: image: ${IMAGE_NAME}:${DEMO_VERSION}-recommendation container_name: recommendation build: context: ./ dockerfile: ${RECOMMENDATION_DOCKERFILE} cache_from: - ${IMAGE_NAME}:${IMAGE_VERSION}-recommendation deploy: resources: limits: memory: 50M restart: unless-stopped ports: - "${RECOMMENDATION_PORT}" environment: - FLAGD_HOST - FLAGD_PORT - RECOMMENDATION_PORT - PRODUCT_CATALOG_ADDR - OTEL_PYTHON_LOG_CORRELATION=true - OTEL_EXPORTER_OTLP_ENDPOINT - OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE - OTEL_RESOURCE_ATTRIBUTES - OTEL_SERVICE_NAME=recommendation - PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python depends_on: product-catalog: condition: service_started otel-collector: condition: service_started logging: *logging # Shipping service shipping: image: ${IMAGE_NAME}:${DEMO_VERSION}-shipping container_name: shipping build: context: ./ dockerfile: ${SHIPPING_DOCKERFILE} cache_from: - ${IMAGE_NAME}:${IMAGE_VERSION}-shipping deploy: resources: limits: memory: 20M restart: unless-stopped ports: - "${SHIPPING_PORT}" environment: - SHIPPING_PORT - QUOTE_ADDR - OTEL_EXPORTER_OTLP_ENDPOINT - OTEL_RESOURCE_ATTRIBUTES - OTEL_SERVICE_NAME=shipping - OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE healthcheck: test: ["CMD-SHELL", "timeout 1 bash -c '>/dev/tcp/localhost/${SHIPPING_PORT}'"] start_period: 10s interval: 5s timeout: 10s retries: 10 depends_on: otel-collector: condition: service_started logging: *logging # ****************** # Dependent Services # ****************** # Flagd, feature flagging service flagd: image: ${FLAGD_IMAGE} container_name: flagd deploy: resources: limits: memory: 75M environment: - FLAGD_OTEL_COLLECTOR_URI=${OTEL_COLLECTOR_HOST}:${OTEL_COLLECTOR_PORT_GRPC} - FLAGD_METRICS_EXPORTER=otel - GOMEMLIMIT=60MiB - OTEL_RESOURCE_ATTRIBUTES - OTEL_SERVICE_NAME=flagd command: [ "start", "--uri", "file:./etc/flagd/demo.flagd.json" ] ports: - "${FLAGD_PORT}" - "${FLAGD_OFREP_PORT}" volumes: - ./src/flagd:/etc/flagd logging: *logging # Valkey used by Cart service valkey-cart: image: ${VALKEY_IMAGE} container_name: valkey-cart user: valkey deploy: resources: limits: memory: 20M restart: unless-stopped ports: - "${VALKEY_PORT}" logging: *logging # ******************** # Telemetry Components # ******************** # Jaeger jaeger: image: ${JAEGERTRACING_IMAGE} container_name: jaeger command: - "--config=file:/etc/jaeger/config.yml" deploy: resources: limits: memory: 400M restart: unless-stopped ports: - "${JAEGER_UI_PORT}" - "${JAEGER_GRPC_PORT}" environment: - JAEGER_HOST - JAEGER_GRPC_PORT - PROMETHEUS_ADDR - OTEL_COLLECTOR_HOST - OTEL_COLLECTOR_PORT_HTTP - MEMORY_MAX_TRACES=5000 volumes: - ./src/jaeger/config.yml:/etc/jaeger/config.yml logging: *logging # Grafana grafana: image: ${GRAFANA_IMAGE} container_name: grafana deploy: resources: limits: memory: 120M 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_PORT}" logging: *logging # OpenTelemetry Collector otel-collector: image: ${COLLECTOR_CONTRIB_IMAGE} container_name: otel-collector deploy: resources: limits: memory: 200M restart: unless-stopped command: [ "--config=/etc/otelcol-config.yml", "--config=/etc/otelcol-config-extras.yml" ] user: 0:0 volumes: - ${HOST_FILESYSTEM}:/hostfs:ro - ${DOCKER_SOCK}:/var/run/docker.sock:ro - ${OTEL_COLLECTOR_CONFIG}:/etc/otelcol-config.yml - ${OTEL_COLLECTOR_CONFIG_EXTRAS}:/etc/otelcol-config-extras.yml ports: - "${OTEL_COLLECTOR_PORT_GRPC}" - "${OTEL_COLLECTOR_PORT_HTTP}" depends_on: jaeger: condition: service_started opensearch: condition: service_healthy logging: *logging environment: - FRONTEND_PROXY_ADDR - IMAGE_PROVIDER_HOST - IMAGE_PROVIDER_PORT - HOST_FILESYSTEM - OTEL_COLLECTOR_HOST - OTEL_COLLECTOR_PORT_GRPC - OTEL_COLLECTOR_PORT_HTTP - POSTGRES_HOST - POSTGRES_PORT - POSTGRES_PASSWORD - GOMEMLIMIT=160MiB # 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=/ - --web.enable-otlp-receiver - --enable-feature=exemplar-storage volumes: - ./src/prometheus/prometheus-config.yaml:/etc/prometheus/prometheus-config.yaml deploy: resources: limits: memory: 300M restart: unless-stopped ports: - "${PROMETHEUS_PORT}:${PROMETHEUS_PORT}" logging: *logging # OpenSearch opensearch: container_name: opensearch build: context: ./ dockerfile: ${OPENSEARCH_DOCKERFILE} cache_from: - ${IMAGE_NAME}:${IMAGE_VERSION}-opensearch deploy: resources: limits: memory: 800M restart: unless-stopped environment: - cluster.name=demo-cluster - node.name=demo-node - bootstrap.memory_lock=true - discovery.type=single-node - OPENSEARCH_JAVA_OPTS=-Xms400m -Xmx400m - DISABLE_INSTALL_DEMO_CONFIG=true - DISABLE_SECURITY_PLUGIN=true # Workaround on OSX for https://bugs.openjdk.org/browse/JDK-8345296 - _JAVA_OPTIONS ulimits: memlock: soft: -1 hard: -1 nofile: soft: 65536 hard: 65536 ports: - "9200" healthcheck: test: curl -s http://localhost:9200/_cluster/health | grep -E '"status":"(green|yellow)"' start_period: 10s interval: 5s timeout: 10s retries: 10 logging: *logging