diff --git a/stacks/park/.env.example b/stacks/park/.env.example new file mode 100644 index 0000000..f49228c --- /dev/null +++ b/stacks/park/.env.example @@ -0,0 +1,16 @@ +# stonehenge-park — host-side tunables. Copy to .env (chmod 600) and fill in. +# The real PARK_API_KEY lives in the vault (secret get nh3-dev/park-api-key), never in git. + +PARK_API_KEY=change-me +# PARK_DB_PATH is fixed to /data/park.db inside the container (named volume). + +# Scheduler knobs (all optional; defaults shown) +#PARK_STALE_DAYS=30 +#PARK_TICK_MINUTES=30 +#PARK_REPUSH_HOURS=24 +#PARK_ALTHING_CHANNEL=henge-crow # empty string disables the althing push entirely +#PARK_SCHEDULER=1 # 0 disables the in-process scheduler + +# DEPLOYED STATE (2026-08-12): PARK_ALTHING_CHANNEL is set EMPTY on nh3-docker so the +# scheduler runs endpoint-only (no per-tick push-fail logs) until althing-cli is wired +# into the container. Set it back to henge-crow once the bus courier is available in-container. diff --git a/stacks/park/README.md b/stacks/park/README.md new file mode 100644 index 0000000..05e4a43 --- /dev/null +++ b/stacks/park/README.md @@ -0,0 +1,44 @@ +# park (stonehenge-park — "the henge") + +Self-contained needs-attention tracker: FastAPI + SQLite (FTS5) + an in-process +scheduler, one container. Source: `gitea.phasefinal.com/vh/stonehenge-park`, +deployed at tag **v1.0.0-beta.1**. Owned by `park-dev`. + +- **Host:** nh3-docker (`10.100.50.40`), compose home `/opt/docker/compose/park/`. +- **Port:** `8420` (host + container). **LAN/WG-internal only — never internet-exposed.** +- **Data:** named volume `park-data` → `/data`; SQLite single file `/data/park.db` + (the sole source of truth). Covered by restic via the host's `/var/lib/docker/volumes` + backup source — no per-volume add needed. (⚠ nh3-docker's restic repo was broken as of + 2026-08-12 — see fleet infra notes.) +- **Secret:** `PARK_API_KEY` from the vault (`secret get nh3-dev/park-api-key`), in the + host `.env` (chmod 600). `/healthz` is unauthenticated; `/park/*` needs the bearer key. +- **Health:** `GET /healthz` → `{"status":"ok"}` (image `HEALTHCHECK` built in). + +## Image is built locally (no registry yet) + +```bash +# on nh3-docker: +cd ~/deploy-src/stonehenge-park # rsync'd from the tag +sudo docker build -t park:v1.0.0-beta.1 . +cd /opt/docker/compose/park && sudo docker compose up -d +``` + +Swap `image:` for a registry ref once one exists (park-dev left the door open). + +## althing wiring (TODO) + +The scheduler posts needs-attention snapshots to althing handle `henge-crow` by +shelling out to `althing-cli post` inside the container. `althing-cli` is **not yet +wired into the container**, so `PARK_ALTHING_CHANNEL` is set **empty** in the host +`.env` (push disabled; REST endpoints fully functional — graceful by design). To +enable: get `althing-cli` reachable in-container (bind-mount + config / sidecar / +host-run), set `PARK_ALTHING_CHANNEL=henge-crow`, recreate. + +## Verify + +```bash +curl -s http://10.100.50.40:8420/healthz # {"status":"ok"} +curl -s http://10.100.50.40:8420/ # UI shell +curl -s -H "Authorization: Bearer $KEY" \ + http://10.100.50.40:8420/park/due-count # {"count": N} +``` diff --git a/stacks/park/compose.yaml b/stacks/park/compose.yaml new file mode 100644 index 0000000..aed5d1f --- /dev/null +++ b/stacks/park/compose.yaml @@ -0,0 +1,17 @@ +# stonehenge-park — nh3-docker. LAN/WG-internal only (port 8420); NOT internet-exposed. +# Image built once from vh/stonehenge-park v1.0.0-beta.1 (infra-ops: docker build -t park:v1.0.0-beta.1 .). +# Build source mirror: ~/deploy-src/stonehenge-park on nh3-docker. .env (chmod 600) holds PARK_API_KEY (vault nh3-dev/park-api-key). +services: + park: + image: park:v1.0.0-beta.1 + container_name: park + restart: unless-stopped + ports: + - "8420:8420" + env_file: + - .env + volumes: + - park-data:/data # SQLite single file /data/park.db — covered by restic (via /var/lib/docker/volumes) + +volumes: + park-data: