Add validator CI + CLAUDE.md; fix dashboard-domain typo (#3)
This commit is contained in:
parent
9de12534a5
commit
19e74af9ca
3 changed files with 108 additions and 1 deletions
66
.forgejo/workflows/validate.yml
Normal file
66
.forgejo/workflows/validate.yml
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
name: Validate observability stack
|
||||
|
||||
# This repo deploys by hand (`docker compose up -d` on beta + the Alloy agent on
|
||||
# each node) with no build step, so nothing caught a malformed compose file, a
|
||||
# broken dashboard JSON, or an unparseable config until it failed live on the
|
||||
# host. This is that missing guard: it parses every YAML/JSON artifact that ships
|
||||
# to a node. It does NOT deploy, and deliberately needs no docker CLI (the
|
||||
# node:20-bookworm job image doesn't ship one) — a YAML parse catches the real
|
||||
# breakage (bad indent / unparseable file) without it.
|
||||
#
|
||||
# Not validated here: the Alloy config (alloy/config.alloy, an HCL-like format,
|
||||
# needs the `alloy` binary) and docker-compose *schema* (unknown-key checks, which
|
||||
# would need the docker CLI). Add either if the churn warrants the extra tooling.
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
pull_request:
|
||||
branches: [main]
|
||||
|
||||
jobs:
|
||||
validate:
|
||||
runs-on: docker
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Dashboards are valid JSON
|
||||
run: |
|
||||
set -euo pipefail
|
||||
python3 - <<'PY'
|
||||
import json, pathlib, sys
|
||||
bad = False
|
||||
files = sorted(pathlib.Path("grafana/dashboards").glob("*.json"))
|
||||
if not files:
|
||||
print("no dashboards found"); sys.exit(1)
|
||||
for f in files:
|
||||
try:
|
||||
json.loads(f.read_text()); print("OK", f)
|
||||
except Exception as e: # noqa: BLE001
|
||||
print("INVALID JSON", f, "-", e); bad = True
|
||||
sys.exit(1 if bad else 0)
|
||||
PY
|
||||
|
||||
- name: YAML artifacts parse (compose + loki + grafana provisioning)
|
||||
run: |
|
||||
set -euo pipefail
|
||||
apt-get update -qq && apt-get install -y -qq python3-yaml >/dev/null
|
||||
python3 - <<'PY'
|
||||
import pathlib, sys
|
||||
import yaml
|
||||
bad = False
|
||||
targets = [
|
||||
pathlib.Path("docker-compose.yml"),
|
||||
pathlib.Path("alloy/docker-compose.agent.yml"),
|
||||
pathlib.Path("loki/config.yml"),
|
||||
*sorted(pathlib.Path("grafana/provisioning").rglob("*.yml")),
|
||||
]
|
||||
for f in targets:
|
||||
if not f.exists():
|
||||
print("MISSING", f); bad = True; continue
|
||||
try:
|
||||
yaml.safe_load(f.read_text()); print("OK", f)
|
||||
except Exception as e: # noqa: BLE001
|
||||
print("INVALID YAML", f, "-", e); bad = True
|
||||
sys.exit(1 if bad else 0)
|
||||
PY
|
||||
41
CLAUDE.md
Normal file
41
CLAUDE.md
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
# thermograph-observability — agent instructions
|
||||
|
||||
The **logging/metrics stack** for the Thermograph fleet: Loki + Grafana on beta,
|
||||
with a Grafana Alloy agent on every node (prod, beta, dev) shipping container and
|
||||
app logs over the WireGuard mesh. Grafana is fronted by beta's Caddy at
|
||||
`dashboard.thermograph.org` (Google SSO, pre-provisioned users only).
|
||||
|
||||
This is **operational infra config, not application code** — there is no build.
|
||||
It deploys by hand: `docker compose up -d` on beta for Loki+Grafana, and the
|
||||
Alloy agent (`alloy/docker-compose.agent.yml`) on each node. See the README for
|
||||
the full per-node procedure.
|
||||
|
||||
## Layout
|
||||
|
||||
- `docker-compose.yml` — the Loki + Grafana stack (runs on beta).
|
||||
- `loki/config.yml` — Loki config (mesh-only, filesystem storage).
|
||||
- `grafana/provisioning/` — datasource (Loki) + dashboard provider, auto-loaded
|
||||
at startup. `grafana/dashboards/*.json` — the dashboards themselves.
|
||||
- `alloy/config.alloy` + `alloy/docker-compose.agent.yml` — the per-node log
|
||||
shipper. The node name comes from `ALLOY_NODE` (set per host).
|
||||
- `caddy-grafana.conf` — the Caddy vhost for `dashboard.thermograph.org` (lives
|
||||
in beta's Caddy config, kept here for reference).
|
||||
- `.env.example` — copy to `.env` on beta before `docker compose up`. `.env` is
|
||||
gitignored; never commit real OAuth secrets or the admin password.
|
||||
|
||||
## Conventions
|
||||
|
||||
- **Every artifact that ships to a node is CI-validated** (`.forgejo/workflows/validate.yml`):
|
||||
both compose files parse, all dashboard JSON is valid, and the Loki/provisioning
|
||||
YAML parses. Keep new dashboards as valid JSON and new config as valid YAML or
|
||||
CI fails. The Alloy config is not yet CI-validated (needs the `alloy` binary).
|
||||
- The public hostname is **`dashboard.thermograph.org`** everywhere — not
|
||||
`grafana.thermograph.org`. Match it in any new comment/config.
|
||||
- Secrets (OAuth client id/secret, admin password) live only in the host `.env`,
|
||||
never in the repo.
|
||||
|
||||
## Branching
|
||||
|
||||
Single `main` branch, no protection. Open a PR against `main`; the validator
|
||||
gates it. Deploying the change to beta / the nodes is a separate manual step
|
||||
(this repo has no deploy automation — a known gap).
|
||||
|
|
@ -5,7 +5,7 @@
|
|||
# Loki over the WireGuard mesh, so Loki must listen on the mesh interface.
|
||||
#
|
||||
# Deploy (on beta): docker compose up -d
|
||||
# Grafana is proxied by beta's Caddy at grafana.thermograph.org (see README);
|
||||
# Grafana is proxied by beta's Caddy at dashboard.thermograph.org (see README);
|
||||
# Loki is NOT public — it binds the mesh IP only, reachable to agents over wg0.
|
||||
|
||||
services:
|
||||
|
|
|
|||
Loading…
Reference in a new issue