ops: STATUS.md — full post-compact pickup (done/pending/next)

This commit is contained in:
Claude 2026-05-30 22:25:55 +02:00
parent 3cfbb5aa3c
commit ee564e865c

45
STATUS.md Normal file
View file

@ -0,0 +1,45 @@
# CannaBuddy build — STATUS / post-compact pickup (2026-05-30 eve)
Read together with **`linux.md`** (server conventions) + **`passwords.md`** (all
creds) — all in this PRIVATE repo (`git.dahlner.de/hydrobuddy/secrets`).
**Goal:** stand up the new VPS `cannabuddy.eu` as a hand-rolled NATIVE stack +
Forgejo, **fresh start** (NO cloud data/tenant/user/device/DB migration — members
re-register, board re-flashes; **only Forgejo data migrates**) → validate →
**v1.0.0** → move the `buddys` tenant + new hardware.
## Box
- New: `181.214.99.11` / `2a0f:5707:aaf1:210c::1`, Debian 12, 4 vCPU (Ryzen 9 7950X), 8 GB.
- SSH **key-only**: claude `~/.ssh/id_ed25519_cannabuddy`, KJ `~/.ssh/id_ed25519`. Password login OFF. Provider console = fallback.
- Old (Netcup): `weed.dahlner.de`, key `~/.ssh/id_ed25519_hydrobuddy` — SHARED box (obico/paperless/livekit/…); only Forgejo migrates; decommission LAST.
- Local repos: `C:\Users\veste\Desktop\HydroBuddy\repos\{cloud,docs,ops}` (`ops` = the `secrets` Forgejo repo).
## DONE (verified)
- **Hardening:** SSH key-only · `ufw` · `fail2ban` (jail.local **systemd backend** — Debian 12 has no auth.log) · unattended-upgrades.
- **CF Origin cert** `/etc/ssl/cannabuddy/{origin.crt,origin.key}` (dir `750 root:caddy`), valid **2041**. CF SSL mode = Full(strict), confirmed working.
- **CF-only origin firewall:** 80/443 (tcp+udp) allowed **only from Cloudflare ranges**; **SSH 22 open to all**. Script `/usr/local/sbin/cf-firewall.sh` (= repo `scripts/cf-firewall.sh`) + weekly `cf-firewall.timer` (Sun 04:30). Verified: via-CF→200, direct-origin→blocked, SSH→ok.
- **Caddy 2.11** — `/etc/caddy/Caddyfile` (= repo `deploy/Caddyfile`). HTTP/3 + security headers. Routes: `cannabuddy.eu`→landing `/var/www/cannabuddy-landing` · `app.`→`:7502` (+`/mqtt`→`:8083`) · `admin.`→`:7502` · `git.`→`:3000` · `status.`→`:3001`. **LIVE: https://cannabuddy.eu serves the landing.** `app.` = 502 until the app deploys.
- **TimescaleDB 16** (2.27.1): DB `cannabuddy`, role `hbcloud`, ext on, **localhost-only**. `DATABASE_URL` in `/etc/cannabuddy/cloud.env` (`640 root:hbapp`) + passwords.md.
- **Mosquitto 2.0.11** installed, default instance **STOPPED** (pending go-auth config).
- **Node 22 + pm2 + pnpm** (corepack).
- **`hbapp`** non-root service user (uid 1000, home `/opt/cannabuddy`, NO sudo) — the app/relay run here.
- **DNS** (Cloudflare, proxied): `cannabuddy.eu`, `app.`, (KJ also added `admin.`, `git.`, `status.`, `www`). NS = Cloudflare.
- **Decisions locked:** data = **pooled + `tenant_id`** (RLS later); broker = **Mosquitto** + per-device **tokens** validated via `mosquitto-go-auth` Postgres backend; **per-tenant device quota**; auth/sessions/passwords already in Postgres (Better-Auth tables `users/sessions/accounts/verifications` + `user_dashboard_prefs`); **relay/bridge = LAST**.
- FW now publishes **~3 s cadence** (clean, oversampled) → on new box store **full-res raw** + Timescale compression (no old noise-decimation throttle needed).
## ⛔ PENDING DECISION (blocks the next step)
**Container runtime for CI.** Old Forgejo = **Docker** (`forgejo:11` + `forgejo/runner:6`, **SQLite** at `/home/dahlner-git/services/forgejo/data`, compose `/home/dahlner-git/services/forgejo/docker-compose.yml`). The CI runner builds **firmware inside ESP-IDF containers**, so the new box needs a container runtime — conflicts with the earlier "no Docker" goal.
**Recommendation (awaiting KJ "Podman OK"):** install **Podman (rootless)** on the new box for **Forgejo + runner + build jobs only**; cloud stack stays **native**. Cloud-deploy job = **host runner** (no container); FW build job = Podman container.
## NEXT (once Podman confirmed)
1. Install Podman (rootless).
2. **Forgejo migrate:** copy `…/forgejo/data` + compose from Netcup → new box; repoint `DOMAIN`/`ROOT_URL` → `git.cannabuddy.eu` + SSH; run; verify clone/push/CI; register runner (host + container labels).
3. Wire the **cloud deploy Action** → builds + `pm2 reload` as `hbapp` (cluster) → **`app.cannabuddy.eu` green** (first deploy = current code on the fresh DB).
4. **New-arch code** (commits → CI ships): `measurements.tenant_id` + Timescale **compression** (≥7 d); `device_credentials` table; `/api/provision` issues per-device opaque tokens + per-tenant quota; **Resend → SendKit** (+ SPF/DKIM/DMARC DNS).
5. **Mosquitto go-auth** (Postgres backend) + WS listener `127.0.0.1:8083` → start mosquitto.
6. **FW relay/bridge** (hbapp/pm2): sub `tele/#` → insert to TimescaleDB stamping `tenant_id`; pub `cmd/<mac>/ota` + `cmd/<mac>/factory-reset`.
7. **Uptime Kuma** → `status.cannabuddy.eu`. **R2 backups:** nightly `pg_dump` → R2 **EU endpoint** + tested restore (creds in passwords.md).
8. **Validate E2E** with a test board → tag **v1.0.0** → re-flash the real board + give the 2 members the new link.
## R2 (backups + images) — creds in passwords.md
Bucket `cannabuddy`, **EU endpoint** `https://e840f5bb6d09cb2c0294f434f35642a9.eu.r2.cloudflarestorage.com`, custom domain `r2.cannabuddy.eu`.