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= thesecretsForgejo 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}(dir750 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(= reposcripts/cf-firewall.sh) + weeklycf-firewall.timer(Sun 04:30). Verified: via-CF→200, direct-origin→blocked, SSH→ok. - Caddy 2.11 —
/etc/caddy/Caddyfile(= repodeploy/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, rolehbcloud, ext on, localhost-only.DATABASE_URLin/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).
hbappnon-root service user (uid 1000, home/opt/cannabuddy, NO sudo) — the app/relay run here.- DNS (Cloudflare, proxied):
cannabuddy.eu,app., (KJ also addedadmin.,git.,status.,www). NS = Cloudflare. - Decisions locked: data = pooled +
tenant_id(RLS later); broker = Mosquitto + per-device tokens validated viamosquitto-go-authPostgres backend; per-tenant device quota; auth/sessions/passwords already in Postgres (Better-Auth tablesusers/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)
- Install Podman (rootless).
- Forgejo migrate: copy
…/forgejo/data+ compose from Netcup → new box; repointDOMAIN/ROOT_URL→git.cannabuddy.eu+ SSH; run; verify clone/push/CI; register runner (host + container labels). - Wire the cloud deploy Action → builds +
pm2 reloadashbapp(cluster) →app.cannabuddy.eugreen (first deploy = current code on the fresh DB). - New-arch code (commits → CI ships):
measurements.tenant_id+ Timescale compression (≥7 d);device_credentialstable;/api/provisionissues per-device opaque tokens + per-tenant quota; Resend → SendKit (+ SPF/DKIM/DMARC DNS). - Mosquitto go-auth (Postgres backend) + WS listener
127.0.0.1:8083→ start mosquitto. - FW relay/bridge (hbapp/pm2): sub
tele/#→ insert to TimescaleDB stampingtenant_id; pubcmd/<mac>/ota+cmd/<mac>/factory-reset. - Uptime Kuma →
status.cannabuddy.eu. R2 backups: nightlypg_dump→ R2 EU endpoint + tested restore (creds in passwords.md). - 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.