services: # OpenTelemetry Collector - receives telemetry from Claude Code otel-collector: image: otel/opentelemetry-collector-contrib:0.115.1 container_name: claude-otel-collector command: ["--config=/etc/otel-collector-config.yml"] volumes: - ./otel-collector-config.yml:/etc/otel-collector-config.yml ports: - "4317:4317" # OTLP gRPC receiver - "4318:4318" # OTLP HTTP receiver - "8889:8889" # Prometheus metrics exporter networks: - claude-telemetry # Prometheus - stores metrics prometheus: image: prom/prometheus:v2.55.1 container_name: claude-prometheus command: - '--config.file=/etc/prometheus/prometheus.yml' - '--storage.tsdb.path=/prometheus' - '--web.console.libraries=/etc/prometheus/console_libraries' - '--web.console.templates=/etc/prometheus/consoles' - '--web.enable-lifecycle' volumes: - ./prometheus.yml:/etc/prometheus/prometheus.yml - prometheus-data:/prometheus ports: - "9090:9090" networks: - claude-telemetry depends_on: - otel-collector # Loki - stores logs loki: image: grafana/loki:3.0.0 container_name: claude-loki ports: - "3100:3100" command: -config.file=/etc/loki/local-config.yaml volumes: - loki-data:/loki networks: - claude-telemetry # Grafana - visualization dashboards grafana: image: grafana/grafana:11.3.0 container_name: claude-grafana ports: - "3000:3000" environment: - GF_SECURITY_ADMIN_USER=admin - GF_SECURITY_ADMIN_PASSWORD=admin - GF_USERS_ALLOW_SIGN_UP=false volumes: - grafana-data:/var/lib/grafana - ./grafana-datasources.yml:/etc/grafana/provisioning/datasources/datasources.yml networks: - claude-telemetry depends_on: - prometheus - loki networks: claude-telemetry: driver: bridge volumes: prometheus-data: loki-data: grafana-data: