Přeskočit na obsah

Runbook — lokální observability stack

Core monitoring stack (Prometheus/Grafana/Loki/Tempo/Alertmanager/Uptime Kuma), Vault, GlitchTip a PostHog běží jako součást výchozí sady profilů run-local-dev.sh (profily monitoring, vault, glitchtip, posthog). Samotný monitoring stack je auto-provisioned (dashboardy, data sources i scrape configy jsou předpřipravené) a nevyžaduje žádné manuální nastavení nad rámec jednorázové opravy oprávnění volumes níže — Uptime Kuma, Vault, GlitchTip a PostHog potřebují jednorázový prvotní krok, protože si samy spravují uživatele/projekty/klíče. Skutečné hodnoty secrets (tokeny, DSN, hesla) žijí pouze v orchestration/.env (gitignored) — nikdy v této dokumentaci ani v gitu.

Tabulka “Default profily” v kořenovém CLAUDE.md je zastaralá — uvádí kratší sadu profilů, než jaká se ve skutečnosti spouští. Autoritativní aktuální seznam je proměnná DEFAULT_PROFILES v orchestration/run-local.sh (a orchestration/run-local-dev.sh, který ji zrcadlí), která dnes navíc obsahuje audit, agent, vault, billing, watchdog, glitchtip, posthog, opsloop, llm, backup, cell a bootstrap nad rámec profilů jmenovaných v tabulce CLAUDE.md. Potřebujete-li vědět, co se spouští ve výchozím stavu, ověřte si přímo tento soubor, ne tabulku.

Profil monitoring nastartuje Prometheus, Grafanu, Loki, Tempo, Alertmanager a Uptime Kuma (plus exportéry/OTEL collector). Všechny jsou předprovisionované — žádné manuální nastavení dashboardů/data sources není potřeba — kromě Uptime Kuma, která vyžaduje prvotní vytvoření admin účtu.

SlužbaURLPoznámky
Grafanahttp://grafana.sencai.localhostVýchozí přihlášení admin/admin, přepsatelné přes GRAFANA_ADMIN_USER/GRAFANA_ADMIN_PASSWORD v orchestration/.env
Prometheushttp://prometheus.sencai.localhostMetriky + query UI
Alertmanagerhttp://alertmanager.sencai.localhostUI pro routing alertů
Uptime Kuma (status page)http://status.sencai.localhostPrvotní krok: první návštěva vyzve k vytvoření admin účtu — stejný vzorec jako u GlitchTip/PostHog níže

Loki quirk: grafana/loki:3.6.x je distroless image bez shellu, wget i curl, takže proti němu nejde spustit obvyklý HTTP healthcheck; compose config místo toho jako liveness check spouští proces loki -version. Samostatně od toho endpoint /ready u Loki v tomto single-node, in-memory-ring nastavení trvale vrací 503 — to je pro tento tvar nasazení očekávané chování, ne známka rozbitého Loki; Loki i tak normálně přijímá loguje a obsluhuje dotazy. Kompletní popis viz orchestration/CLAUDE.md.

Jednorázová oprava vlastnictví volumes: Docker vytváří bind-mount adresáře jako root, ale tyto kontejnery běží pod non-root uživateli. Po prvním startu profilu monitoring spustit:

Terminál
sudo chown -R 65534:65534 ~/sencai_volumes/prometheus ~/sencai_volumes/alertmanager
sudo chown -R 10001:10001 ~/sencai_volumes/loki ~/sencai_volumes/tempo
sudo chown -R 472:472 ~/sencai_volumes/grafana

(Uprav základní cestu, pokud jsi přepsal LOCAL_VOLUME_PATH/VOLUME_PATH v .env.) Stejná poznámka v kontextu s ostatními opravami vlastnictví volumes (např. Forum pict-rs) je v orchestration/CLAUDE.md.

Lokální vývoj má Vault ve výchozím stavu zapečetěný, se souborovým (file-backed) storage — VAULT_DEV_MODE=false je default v orchestration/.env.example. Na čerstvém volume se kontejner spustí zapečetěný, bez jakéhokoliv známého root tokenu — jednou je nutné projít standardní init/unseal flow:

Terminál
docker exec -it sencai-vault vault operator init
# vygenerované unseal klíče + initial root token uložit MIMO repozitář
docker exec -it sencai-vault vault operator unseal # opakovat se 3 z 5 klíčů

Konfiguraci storage/listeneru najdeš v orchestration/config/vault/vault-config.hcl, navazující bootstrap KV/AppRole v orchestration/scripts/vault-init.sh (očekává VAULT_TOKEN nastavený na root token z kroku init výše).

Dev mode je čistě opt-in, pro jednorázový/zahazovatelný lokální stroj: nastavením VAULT_DEV_MODE=true a VAULT_DEV_ROOT_TOKEN v orchestration/.env získáš in-memory storage, automatické odpečetění při každém startu a pevně daný root token — v tomto módu nic nepřežije rekreaci kontejneru. Nepoužívat dev mode jako šablonu pro staging/produkci a nepředpokládat, že je to to, co dostaneš z čerstvého lokálního checkoutu ve výchozím stavu — zapečetěná cesta se souborovým storage je to, co se skutečně spouští, pokud jsi explicitně nepřepnul flag.

Pokud Vault i přesto ukazuje unhealthy, i když kontejner běží, nejdřív zkontroluj docker logs sencai-vault — pokud jsi ve výchozím zapečetěném módu, jde často jen o to, že ještě neproběhl unseal krok.

GlitchTip (self-hosted Sentry-kompatibilní error tracking)

Section titled “GlitchTip (self-hosted Sentry-kompatibilní error tracking)”
  1. První návštěva http://glitchtip.sencai.localhost/ vytvoří prvního uživatele jako org ownera. Úvodní krok “vyber platformu” je kosmetický — ovlivňuje jen ukázkový onboarding snippet, ne funkčnost — při nejistotě zvolit cokoliv (např. node).
  2. GlitchTip REST API (Sentry-API-kompatibilní) vyžaduje osobní API token, vytvořený v Settings → Auth Tokens — wizard pro založení organizace ho automaticky nevytváří.
  3. Každá služba nakonfigurovaná s SENTRY_DSN (viz docker-compose.core.yml, docker-compose.cloud.yml atd.) potřebuje GlitchTip projekt + klíč. Aktuálně celá platforma sdílí jeden projekt (všechny backend služby publikují na stejné DSN), protože takto je SENTRY_DSN už zapojeno jako jedna sdílená env proměnná napříč ~11 službami — rozdělení na per-service projekty by nejdřív vyžadovalo zavedení per-service názvů env proměnných v každém compose souboru. Ne každý mikroservis má SENTRY_DSN zapojené — aktuálně je nastaveno na api-manager, backend, frontend, webhook-publisher, auth-service-consumer, billing-adapter, git-connector, notification-service, cloud-connector/cloud-connector-worker a opsloop-consumer. Zapojení do nové služby znamená přidat SENTRY_DSN=${SENTRY_DSN:-} do env bloku dané služby v compose a volat Sentry.init() podmíněně na tom, že je nastavené (viz F3.SECURITY.02 v PHASE-3-PLAN.md).
  4. Gotcha server-side vs. client-side DSN: hostname *.sencai.localhost se uvnitř kontejnerů resolvuje na loopback (RFC 6761 — stejná třída problému jako dřívější HSTS/Chromium vyšetřování), ne na Traefik. Tedy:
    • SENTRY_DSN (konzumováno backend službami běžícími uvnitř Dockeru) musí ukazovat na interní název služby: http://<key>@glitchtip-web:8000/<project-id>.
    • NUXT_PUBLIC_SENTRY_DSN (bundlováno do prohlížeče) musí používat veřejný, Traefikem routovaný hostname: http://<key>@glitchtip.sencai.localhost/<project-id>.
    • Prohození znamená buď “žádné chyby se nikdy nezobrazí” (server-side ukazuje na browser hostname, connection refused na loopback vlastního kontejneru), nebo DSN funkční jen z prohlížeče (client-side ukazuje na interní název, který prohlížeč vůbec nedokáže resolvovat).
  5. Po zapojení DSN(s) do orchestration/.env je nutné dotčené služby rekreovat (ne jen restartovat) — env proměnné se zapékají při vytvoření kontejneru:
    Terminál
    ./run-local-dev.sh up -d api-manager cloud-connector cloud-connector-worker \
    billing-adapter git-connector notification-service opsloop-consumer \
    auth-service-consumer webhook-publisher backend frontend
  6. Ověřit end-to-end zkušební událostí (issue pak smazat):
    Terminál
    docker exec sencai-api-manager-1 node -e "
    const S = require('@sentry/node');
    S.init({ dsn: process.env.SENTRY_DSN });
    S.captureException(new Error('smoke test'));
    S.flush(5000).then(() => process.exit(0));
    "
  1. První návštěva http://posthog.sencai.localhost/ provede založením org + projektu a krokem “zvol launch mode” (live implementace vs. jen experimentování) — pro lokální vývoj je jedno co zvolíte, ovlivňuje to jen onboarding tipy.
  2. Veřejný API klíč projektu (phc_..., na stránce project settings) je write-only capture klíč — bezpečný pro embed na klientu, přesně to co očekává NUXT_PUBLIC_POSTHOG_KEY (viz plugins/posthog.client.ts ve frontendu, gatováno za cookie consent bannerem).
  3. Na rozdíl od GlitchTip DSN zůstává NUXT_PUBLIC_POSTHOG_HOST veřejný http://posthog.sencai.localhost i přesto, že jde taky o čistě client-side použití — server-side PostHog capture cesta v tomto kódu dnes neexistuje, takže container-vs-browser DNS rozdíl zde nenastává.
  4. Hlubší konfigurace na straně PostHog (dashboardy, insighty, kohorty, feature flags) vyžaduje osobní API klíč (Settings → Personal API Keys), odlišný od projektového capture klíče — capture klíč umí jen zapisovat eventy, nic nečte ani nekonfiguruje.

Lago je self-hosted usage-based billingový/metering systém stojící za billing-adapter (port 3600, ADR-002) — běží jako getlago/api + getlago/front (obě pinované na v1.30.0) a je dostupný na http://lago.sencai.localhost: API/GraphQL rozhraní je routováno pod /api, /rails a /graphql na tomto hostu, zatímco holý host obsluhuje Lago UI. Je to Rails aplikace s has_secure_password (bcrypt, sloupec password_digest) — v tomto self-hosted nastavení není žádný self-service “zapomenuté heslo” flow. Reset hesla uživatele přímo:

Terminál
docker exec sencai-lago-api bundle exec rails runner "
u = User.find_by(email: 'user@example.com')
u.update!(password: 'NOVE_HESLO', password_confirmation: 'NOVE_HESLO')
"

Ověřit přes login GraphQL mutaci před předáním nového hesla zpět:

Terminál
curl -s -X POST -H 'Host: lago.sencai.localhost' -H 'Content-Type: application/json' \
-d '{"query":"mutation { loginUser(input: { email: \"user@example.com\", password: \"NOVE_HESLO\" }) { token } }"}' \
http://localhost/graphql