Runbook — Watchtower can't scrape CMMD /metrics
Watchtower's Prometheus reports `up{job="cmmd-app-metrics"} == 0`. CMMD itself may still be healthy — this alert specifically means the metrics-export path is broken, which leaves us flying blind on cost + usage.
| Field | Value |
|---|---|
| Severity | P1 (visibility loss, not customer impact) |
| Owner | @aphaiboon |
| Alert source | Watchtower — up{job="cmmd-app-metrics"} == 0 for 5m OR absent(cmmd_product_ai_cost_24h_cents) for 10m |
| Estimated time | 5–15 min |
| Required access | Watchtower (Coolify env), Railway (CMMD env), Prometheus UI |
Symptom
Section titled “Symptom”ntfy push: “Watchtower scrape of cmmd.ai/metrics is down”. CMMD app itself may be perfectly healthy (Watchtower → CMMD app probe tile still green); only the metrics scrape is broken.
Why this matters
Section titled “Why this matters”Without /metrics, all of Watchtower’s CMMD-internal tiles go blank:
- Today’s AI spend
- Per-provider usage gauges
- Database health gauge
- HTTP request rate
- Active users
We lose visibility into cost-burn (the P0-class signal). The app still serves customers fine.
Most likely causes
Section titled “Most likely causes”- Token mismatch —
CMMD_METRICS_TOKENin watchtower’s Coolify env doesn’t matchPROMETHEUS_BEARER_TOKENin CMMD’s Railway env. Probably the value drifted (rotated on one side). - CMMD app down — the
/metricsendpoint can’t respond because the whole app isn’t responding. In that case thecmmd-appprobe tile is also red → see runbook-cmmd-app-down first. - Network path broken — Cloudflare blocking the bearer-auth request, or Coolify can’t reach cmmd.ai
- Token unset on the watchtower side —
CMMD_METRICS_TOKENnot set on Coolify; Prometheus targets page shows401 unauthorizedfor the scrape.
Diagnose
Section titled “Diagnose”-
Open Watchtower → Connections → Prometheus →
/targets→ findcmmd-app-metrics. Check the error message. -
If “401 unauthorized”: token mismatch.
-
If “context deadline exceeded”: network path.
-
Manually curl from your machine:
Terminal window # No bearer — should 401curl -i https://cmmd.ai/metrics# With current token (the working one)curl -i -H "Authorization: Bearer <CMMD_PROMETHEUS_BEARER_TOKEN>" https://cmmd.ai/metrics# Expect: 200 + prom-format text
Mitigate
Section titled “Mitigate”Token mismatch
Section titled “Token mismatch”- CMMD → Railway → env → reveal
PROMETHEUS_BEARER_TOKEN. (OrPROMETHEUS_SCRAPE_TOKEN—server/observability/prometheus.tsaccepts either.) - Watchtower → Coolify → env → set
CMMD_METRICS_TOKENto that value. - Restart watchtower’s prometheus container:
docker compose restart prometheus(or via Coolify UI). - Watch the
/targetspage — within 30s thecmmd-app-metricstarget should flip from DOWN to UP.
Token unset
Section titled “Token unset”Same as above — set the env var fresh on Coolify side.
Network path broken
Section titled “Network path broken”- From inside the Coolify host:
curl -i https://cmmd.ai/metrics— does it reach cmmd.ai? - If the same curl works from your laptop but not from Coolify → outbound block on Coolify side. Investigate networking.
CMMD app down
Section titled “CMMD app down”Follow runbook-cmmd-app-down first. The metrics scrape will recover automatically once the app is back.
Verify resolved
Section titled “Verify resolved”- Watchtower → Prometheus →
/targets→cmmd-app-metricsshows UP - Query in Prometheus:
cmmd_product_ai_requests_24h_totalreturns data - Watchtower home dashboard tiles populated
Escalate
Section titled “Escalate”- If the token CAN’T be found in either env → rotate: generate a new strong token, set in both Railway + Coolify, restart both
- If you suspect a leaked token → rotate immediately
Related
Section titled “Related”- runbook-cmmd-app-down
server/observability/prometheus.ts— token-checking source