The hub is a small-footprint stack: one Next.js process, one SQLite database, one worker process, an encrypted secret vault, plus a Mailcow server for email. Everything designed to run on a single commodity VPS and scale horizontally as the fleet grows (see §11 Scaling plan).
Component layout
| Component | What it does |
|---|---|
| Next.js 16 (Turbopack) | Serves both the public marketing site and the admin console at /admin/*. Pages + App Router hybrid. |
| SQLite (better-sqlite3) | Canonical state. Path: ./data/app.db. WAL mode on; versioned migrations in db/migrations/ run on first boot. |
| Worker process (worker/index.ts) | Holds a database lease (one leader at a time). Executes jobs: SSH probes, benchmarks, installs, backups, scoring ticks, tip polls, rich-list refresh. |
| SSH fleet | Per-node ed25519 keys stored in a libsodium-encrypted vault. Every remote action is a shell script + captured stdout. Pooled connections (v0.7.8z14) for low-overhead reuse. |
| Mailcow | Independent mail server on the same VPS. Provides IMAP/SMTP/webmail for authentication and hub-domain mailboxes. |
| iron-session cookie | Encrypted session state. One active account in scope at a time; add-more-accounts switcher lives in the Account widget. |
Firewall (Cerberus)
Cerberus is the hub’s firewall control plane for managed nodes. Three endpoints drive the lifecycle: /api/hub/nodes/[id]/firewall/bootstrap installs UFW and applies the initial ruleset, /reconcile re-pushes the desired state and sweeps drift, and /state reads the live snapshot from the node. Every probe cycle re-evaluates posture against the desired ruleset; drift surfaces on the node card within the next tick (~30s budget). Mutations are gated on fresh-admin-confirm and write to admin_audit with operator email, target, action, and result — the full audit trail is the integrity guarantee. Bootstrap budgets ~8s end-to-end on a warm SSH pool; reconcile and state stay under 2s in steady state.
Deployment model
- Source:
/home/ancientholdings/ancientholdings-websiteon the VPS. - Runtime: PM2 manages the Next.js server + worker as separate processes. Nginx fronts the site on port 443 with a Let’s-Encrypt cert.
- Workflow: edit locally → push to GitHub → deploy script on the server pulls +
npm ci+npm run build+ PM2 reloads. Thedeployskill automates the whole triple.
Data flow at a glance
- Operator action(e.g. “run a benchmark”) → HTTP request to Next.js → insert a row in
jobs→ worker dequeues + SSHes into the node + runs the benchmark script + writes the result back to SQLite → UI polls for status. - Background ticks (every 30s / 60s / hourly / daily) fire from the worker: chainweb-tip poller, scoring tick, rich-list refresh, daily mint, etc.
- Customer nodes never talk to the hub directly — all communication is hub-initiated SSH. The hub pulls data from nodes; nothing is pushed.