secrets/STATUS.md

5 KiB

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.