From ee564e865c6e8d346398b872893117bed24e7bd8 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 30 May 2026 22:25:55 +0200 Subject: [PATCH] =?UTF-8?q?ops:=20STATUS.md=20=E2=80=94=20full=20post-comp?= =?UTF-8?q?act=20pickup=20(done/pending/next)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- STATUS.md | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 STATUS.md diff --git a/STATUS.md b/STATUS.md new file mode 100644 index 0000000..5fdeb22 --- /dev/null +++ b/STATUS.md @@ -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//ota` + `cmd//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`.