spacetrace
EN
Download

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
Binaries
spacetrace hubfleetAlertsThe terminal
7 targets · 6 reporting · 1 silent for 3 days
HostRootFreeGrowthLast 14 daysFills in
db-02/var/lib/postgresql18.2 GiB / 500 GiB+3.1 GiB/day6 days
nas/volume1/backups402 GiB / 8.0 TiB+41 GiB/day10 days
srv-01/srv120 GiB / 400 GiB+1.4 GiB/day85 days
ci-runner-1/var/lib/docker96 GiB / 250 GiB−2.0 GiB/day— r² 0.11
build-03/home1.1 TiB / 2.0 TiB— 2 snapshots
mail/var/mail— capacity not recorded+180 MiB/day
A blank forecast is a refusal to guess, not a missing number. The target's own page says which condition failed.

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.

  1. Make an admin token and a config

    head -c 32 /dev/urandom | od -An -tx1 | tr -d ' \n' > admin-token
    db = "/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.

  2. 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 nas
  3. Point 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.

  4. 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.

CredentialCan doCannot do
Agent tokenPush a snapshotRead the dashboard or the API
Admin tokenRead everything, manage tokens and rulesPush 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 /snapshotsAgent token
GET /api/fleetAdmin token
GET /target?host=&root=Admin token
GET /alertsAdmin token
GET /tokensAdmin 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.