Forty machines. One page.
Your servers scan themselves and report in. The disk that fills up first is at the top. The hub never touches the machines it watches.
docker pull ghcr.io/unalcakir28/spacetrace-hub:main| Host | Root | Free | Growth | Last 14 days | Fills in |
|---|---|---|---|---|---|
| db-02 | /var/lib/postgresql | 18.2 GiB / 500 GiB | +3.1 GiB/day | 6 days | |
| nas | /volume1/backups | 402 GiB / 8.0 TiB | +41 GiB/day | 10 days | |
| srv-01 | /srv | 120 GiB / 400 GiB | +1.4 GiB/day | 85 days | |
| ci-runner-1 | /var/lib/docker | 96 GiB / 250 GiB | −2.0 GiB/day | — r² 0.11 | |
| build-03 | /home | 1.1 TiB / 2.0 TiB | — | — 2 snapshots | |
| /var/mail | — capacity not recorded | +180 MiB/day | — |
Drawn rather than screenshotted. The real dashboard is server-rendered HTML — a self-hosted tool that needs an npm install before it will show you a page is a worse tool.
Set it up
Two credentials, one config file, and one line added to each agent. There is nothing else to stand up.
Make an admin token and a config
head -c 32 /dev/urandom | od -An -tx1 | tr -d ' \n' > admin-tokendb = "/var/lib/spacetrace-hub/hub.sqlite" listen = "0.0.0.0:8080" admin_token_file = "/run/secrets/admin-token" keep_per_target = 90
Save it as hub.toml, then docker compose up -d — or run the binary directly and validate the config before serving.
Sign in and create an agent token
Open the hub, sign in with the contents of admin-token, and create a token on the Agents page. Or do it from the command line.
spacetrace-hub --config hub.toml token nasPoint each agent at it
spacetrace-agent --config /etc/spacetrace/agent.toml push https://hub.example.com --token <agent token>Add that to the agent's schedule and the fleet fills itself in. Re-pushing is harmless: a snapshot already present with the same host, root and start time is skipped.
Put TLS in front of it
Before exposing the hub beyond your own network, terminate TLS in a reverse proxy. The session cookie is HttpOnly and SameSite=Strict; the Secure flag comes from serving it over HTTPS.
Two credentials, on purpose
A token sitting in a config file on a NAS should not be a key to the whole fleet's inventory. So an agent token is not a dashboard credential — and the reverse holds too.
Agent tokens are stored as SHA-256 hashes, so a copy of the database is not a set of working credentials. Revoking keeps the record and stops the token working immediately.
Both directions are covered by tests.
| Credential | Can do | Cannot do |
|---|---|---|
| Agent token | Push a snapshot | Read the dashboard or the API |
| Admin token | Read everything, manage tokens and rules | Push snapshots |
The forecast is the feature held back hardest
It is the one most likely to be wrong, so it is the one that refuses to answer most often. “Fills in N days” appears only when all of these hold.
At least three snapshots, spanning at least a day
Two points always make a perfect line. A day is the shortest span in which a daily pattern can show up at all.
A linear fit of r² ≥ 0.5
Disk usage is frequently not linear. A log rotation or a one-off restore will happily produce a fitted line whose slope means nothing.
A capacity that was actually measured
Without the filesystem's real size there is nothing to fill. The hub does not guess it from the largest total it has seen.
An answer inside ten years
“Fills in 4,000 days” is arithmetic, not information.
Growth and the forecast are different numbers
Growth is measured on the scanned folder. The forecast projects the filesystem's remaining space at that rate. The pages say which is which rather than blending them into one reassuring figure.
Alerts
Threshold rules, delivered by webhook. Three kinds, each with a cooldown so a filling disk does not become a stream of identical messages:
- Free space below a percentage
- Growth above a rate
- A forecast landing inside a horizon
Email delivery is not built yet, and there is one admin credential rather than per-person logins.
HTTP API
| GET /health | — |
|---|---|
| POST /snapshots | Agent token |
| GET /api/fleet | Admin token |
| GET /target?host=&root= | Admin token |
| GET /alerts | Admin token |
| GET /tokens | Admin token |
Why there is no rollup table
Snapshots are kept in the same store the command line and the agent use, unchanged. The hub keeps no summary table of its own, so there is nothing that can drift out of step with the snapshots it came from.
What an agent pushes is the same file it stores locally, so nothing is converted on either side, and the diff on a target's page is computed by the same code that runs on your laptop.