Files
rmm-backend/CLAUDE.md
Kaushik c929176cfa feat: per-site SHIFT path with video search, fix agent token injection, accept cpu_temp
- deploy_agent.sh: agent v3.3-shift — use dashboard-configured SHIFT path for
  file fetch/search (SR/SHIFT sites have no TAKELEAP folder), date fast-path;
  fix installer discarding the injected agent token (sentinel was being
  rewritten by the server's placeholder replace, agents ended up tokenless)
- central_api_prototype.py: replace only the token assignment when serving the
  installer; add cpu_temp to TelemetryPayload (agents already send it, it was
  silently dropped); new endpoints set-shift-path, request-search,
  search-results; heartbeat response now carries shift_path + pending search
- commands.json: restore last_reboot/dummy, add update_diag diagnostic
- CLAUDE.md: document deployment layout, procedures, and gotchas
2026-07-16 17:31:33 +05:30

6.3 KiB
Raw Permalink Blame History

SeekRight Pulse RMM — Production Deployment Map

This VM (vm3-mint, LAN 192.168.1.201, Tailscale 100.79.183.41) is the production server for the SeekRight Pulse RMM system. Field agents and the public dashboard both talk to services running here.

Architecture

Internet
  │
  ▼
Synology reverse proxy (takeleapindia.synology.me / 106.51.70.111)
  ├── https://rmm.seekright.com          → this VM : vite port (currently 4173)
  └── https://rmm-backend.seekright.com  → this VM : 8000
                                                │
Field agents (X-Agent-Token) ───────────────────┤
                                                ▼
                        FastAPI backend (uvicorn :8000, 4 workers)
                                                │
                                MongoDB localhost:27017, db `rmm_db`

Components

Backend — /opt/rmm-backend

  • FastAPI app central_api_prototype.py, run by systemd rmm-backend.service (User=root): venv/bin/uvicorn central_api_prototype:app --host 0.0.0.0 --port 8000 --workers 4
  • Env: systemd EnvironmentFile=/opt/rmm-backend/.env injects vars at service start. The APP_ENV / .env.production / .env.development logic in the code is mostly vestigial here: values from .env are already in the process environment and load_dotenv never overrides them. Editing .env requires a service restart to take effect.
  • Data: MongoDB rmm_db (clients, logs, config collections). Alerts go to Rocket.Chat via ROCKETCHAT_WEBHOOK_URL.
  • commands.json = whitelist of commands agents may run. Read from disk per request (no restart needed). Also editable live from the dashboard config editor (/api load/save endpoints) — meaning production edits land in the working tree and will conflict with git pull (see gotchas).
  • Agent auth: agents send X-Agent-Token (value AGENT_TOKEN in .env). Mode lives in Mongo config._id=agent_auth: grace (default — tokenless legacy agents still accepted) or strict (reject without token). Flip with set_strict.py only after every field agent has been updated (deploy_agent.sh / the update_agent command).
  • Dashboard login: POST /api/login, credentials DASHBOARD_USERNAME / DASHBOARD_PASSWORD from .env, JWT signed with JWT_SECRET_KEY.

Frontend — /opt/rmm-ui

  • React + Vite, run by systemd rmm-frontend.service (User=root): npm run dev -- --mode production (a vite dev server, not a static build).
  • Port is set in vite.config.js (server.port, currently 4173 — must match the Synology reverse-proxy upstream); allowedHosts: ["rmm.seekright.com"] must include the public hostname or vite rejects proxied requests.
  • Vite watches files: pulled code changes hot-reload automatically, and a vite.config.js change makes vite restart itself — BUT an in-process restart keeps whatever port vite already bound (including an auto-bumped one like 4174 after a port collision). To change ports for real: sudo systemctl restart rmm-frontend.service.
  • API base URL comes from /opt/rmm-ui/.env.production (VITE_API_BASE_URL=https://rmm-backend.seekright.com).

Reverse proxy — Synology (NOT on this VM)

  • No nginx/apache runs on this VM. TLS + routing for both public hostnames is done on the Synology at takeleapindia.synology.me (106.51.70.111).
  • If the vite port changes in vite.config.js, the Synology reverse-proxy upstream port must be updated to match — otherwise the site 502s. This exact thing happened 2026-07-16 (commit dc604a4 moved 4173 → 6173).

Field agents (remote machines)

  • Run /opt/seekright-agent/client_agent_prototype.py on each monitored node; poll GET /api/get-command and push POST /api/telemetry.
  • Installed/updated via deploy_agent.sh (served by the backend; in strict mode downloading it requires a valid agent token).

How to deploy

Backend:

cd /opt/rmm-backend
git status                      # working tree should be clean — see gotchas
git pull
sudo systemctl restart rmm-backend.service
systemctl status rmm-backend.service --no-pager -n 20   # check for crash loop
curl -s -o /dev/null -w '%{http_code}\n' http://localhost:8000/docs  # expect 200

Frontend:

cd /opt/rmm-ui
git pull                        # vite hot-reloads; restarts itself on config change
# only if deps changed: npm install && sudo systemctl restart rmm-frontend.service
curl -s -o /dev/null -w '%{http_code}\n' -H 'Host: rmm.seekright.com' http://localhost:4173/
curl -sk -o /dev/null -w '%{http_code}\n' https://rmm.seekright.com/   # via Synology

Gotchas / history

  • Don't hand-edit tracked files on this server (commands.json, .env are tracked in git). Local edits block git pull. Commit changes to the repo instead. Dashboard edits to commands.json also dirty the tree — push them upstream after changing them.
  • 2026-07-16: pull of dc604a4 changed the vite port 4173 → 6173 and broke https://rmm.seekright.com (Synology still forwarded to 4173). Resolved by reverting vite.config.js to port 4173 in the working tree. That revert is a LOCAL change to a tracked file — commit and push it (or the next pull will conflict and re-break the site by pulling 6173 back in).
  • The backend service must be restarted after every backend pull — uvicorn has no auto-reload in the unit. A long-running process can silently serve weeks-old code (happened Jul 6 → Jul 16).
  • Adding a telemetry field takes THREE places: agent payload (in deploy_agent.sh), TelemetryPayload in central_api_prototype.py, and the UI. Pydantic silently DROPS any field missing from TelemetryPayload — agents sent cpu_temp for a while with the backend discarding it and no error anywhere (found 2026-07-16).
  • Ports on this VM: 8000 backend, 6173 rmm-ui vite, 5173 auditor-portal vite (localhost only), 7514 + others auditor portal, 44304433 MeshCentral, Grafana also runs here. Check ss -tlnp before assigning a new port.

Other services on this VM (not part of RMM deploys)

  • meshcentral.service — MeshCentral remote management (node, ports 44304433)
  • grafana — monitoring dashboards
  • /opt/auditor-portal — separate project (its own vite/node dev servers)