# TicketLab lab observability — Grafana + Tempo + Loki + OTEL Collector (+ Prometheus) # Start: docker compose up -d # UI: http://localhost:3001 (admin / admin) # OTLP: http://localhost:4318 (HTTP) | localhost:4317 (gRPC) services: otel-collector: image: otel/opentelemetry-collector-contrib:0.120.0 command: ["--config=/etc/otelcol/config.yaml"] volumes: - ./observability/otel-collector-config.yaml:/etc/otelcol/config.yaml:ro ports: - "4317:4317" # OTLP gRPC - "4318:4318" # OTLP HTTP - "8889:8889" # collector Prometheus metrics (optional) depends_on: - tempo - loki - prometheus tempo: image: grafana/tempo:2.7.1 command: ["-config.file=/etc/tempo/tempo.yaml"] volumes: - ./observability/tempo.yaml:/etc/tempo/tempo.yaml:ro - tempo-data:/var/tempo ports: - "3200:3200" # Tempo HTTP / API loki: image: grafana/loki:3.4.2 command: ["-config.file=/etc/loki/loki.yaml"] volumes: - ./observability/loki.yaml:/etc/loki/loki.yaml:ro - loki-data:/loki ports: - "3100:3100" prometheus: image: prom/prometheus:v3.2.1 volumes: - ./observability/prometheus.yml:/etc/prometheus/prometheus.yml:ro - prometheus-data:/prometheus ports: - "9090:9090" # Host scrape: app on the host publishing GET /metrics extra_hosts: - "host.docker.internal:host-gateway" grafana: image: grafana/grafana:11.5.2 environment: GF_SECURITY_ADMIN_USER: admin GF_SECURITY_ADMIN_PASSWORD: admin GF_AUTH_ANONYMOUS_ENABLED: "true" GF_AUTH_ANONYMOUS_ORG_ROLE: Viewer GF_USERS_DEFAULT_THEME: dark volumes: - ./observability/grafana/provisioning:/etc/grafana/provisioning:ro - grafana-data:/var/lib/grafana ports: - "3001:3000" depends_on: - tempo - loki - prometheus volumes: tempo-data: loki-data: prometheus-data: grafana-data: