services: app: environment: OTEL_EXPORTER_OTLP_ENDPOINT: http://otel-collector:4318 OTEL_EXPORTER_OTLP_PROTOCOL: http/protobuf OTEL_METRIC_EXPORT_INTERVAL: "15000" otel-collector: image: ${KNOWLEDGE_HUB_COLLECTOR_IMAGE:-otel/opentelemetry-collector-contrib:0.162.0-amd64@sha256:340885ab6f46822374f00c58c067396b53b8d612559842e8821585567579d9e3} restart: unless-stopped command: ["--config=/etc/otelcol-contrib/config.yaml"] volumes: - ./deploy/observability/collector.yaml:/etc/otelcol-contrib/config.yaml:ro read_only: true security_opt: ["no-new-privileges:true"] networks: [knowledge-hub-internal] prometheus: image: prom/prometheus:v3.14.0@sha256:5ce7540c3c00ef4ab0c9d2c995c6a5b9c421f44b4a115d97a2c7af3b1c21cbb0 restart: unless-stopped command: ["--config.file=/etc/prometheus/prometheus.yml", "--storage.tsdb.path=/prometheus", "--storage.tsdb.retention.time=7d"] volumes: - ./deploy/observability/prometheus.yaml:/etc/prometheus/prometheus.yml:ro - prometheus-data:/prometheus read_only: true security_opt: ["no-new-privileges:true"] networks: [knowledge-hub-internal] grafana: image: grafana/grafana:12.4.0@sha256:b0ae311af06228bcfd4a620504b653db80f5b91e94dc3dc2a5b7dab202bcde20 restart: unless-stopped environment: GF_SECURITY_ADMIN_USER: ${KNOWLEDGE_HUB_GRAFANA_USER:-admin} GF_SECURITY_ADMIN_PASSWORD: ${KNOWLEDGE_HUB_GRAFANA_PASSWORD:?Set a private Grafana password for observability} GF_USERS_ALLOW_SIGN_UP: "false" volumes: - ./deploy/observability/grafana-datasource.yaml:/etc/grafana/provisioning/datasources/knowledge-hub.yaml:ro - grafana-data:/var/lib/grafana ports: - "127.0.0.1:${KNOWLEDGE_HUB_GRAFANA_PORT:-13000}:3000" read_only: true security_opt: ["no-new-privileges:true"] networks: [knowledge-hub-internal] volumes: prometheus-data: grafana-data: