trove

module
v0.3.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 4, 2026 License: MIT

README

Trove

CI Release

One pane of glass for everything running in your homelab. Small agents sit next to your workloads — Docker hosts, Kubernetes clusters, Proxmox nodes, plain Linux boxes — and push what they see to one server: what's running, where, what version, whether it's healthy, whether its image is outdated, and whether it's still reporting at all.

Trove dashboard

Read-only by design. Trove can never deploy, restart, exec into, or edit anything. There is no code path that mutates a workload — agents only ever issue read/list calls to their platforms. This is an architectural constraint, not a feature toggle, and it's the project's one hard rule.

Features

  • Service catalog across platforms — containers, K8s workloads (with pods nested under their Deployments), Proxmox VMs/LXCs, and systemd units, all in one normalized view grouped by host.
  • Health + heartbeats — platform health where it exists (Docker healthchecks, K8s readiness), plus server-side staleness: an agent that goes quiet flags itself and all its services within ~90 seconds.
  • Image freshness — the server checks registries (batched, cached, rate-limit-aware) and badges services whose running image is behind its tag.
  • Alerts & digest — instant notifications via webhook / Discord / ntfy when a host stops reporting, a service goes unhealthy or dies, or an image falls behind — with recovery notices, flap suppression, and a scheduled email digest. See docs/alerts.md.
  • State-change events — a feed of started/stopped/unhealthy/appeared/removed (30-day retention, configurable).
  • Fast, dense dashboard — no framework, keyboard-driven (/ filter, j/k navigate, enter for details), auto-refreshing.
  • Trivial to operate — one static binary (or container) per role, SQLite storage, automatic schema migrations, push-model agents that work from behind NAT.

Quickstart (5 minutes)

Requires Docker with Compose on the machine that will host the dashboard.

mkdir trove && cd trove
curl -fsSLO https://raw.githubusercontent.com/techdox/trove/main/examples/docker-compose.yml

export TROVE_TOKEN=trove_$(openssl rand -hex 24)
docker compose up -d

Open http://localhost:8080. This host's containers appear within ~30 seconds. That's the whole install: a server plus a Docker agent watching the same machine.

⚠️ The dashboard has no authentication yet — keep it on a trusted network (LAN/VPN/tailnet) or behind an authenticating reverse proxy. See Security model.

Adding more hosts and platforms

Every agent needs its own token, minted on the server:

docker compose exec server trove-server agent create <name>
# e.g.: agent create docker-nas, agent create k8s-homelab, agent create proxmox

Then follow the guide for the platform:

Platform Agent Guide
Docker host trove-agent-docker docs/agents/docker.md
Kubernetes cluster trove-agent-k8s docs/agents/kubernetes.md
Proxmox VE cluster trove-agent-proxmox docs/agents/proxmox.md
Bare-metal Linux (systemd) trove-agent-local docs/agents/local.md

Container images (multi-arch amd64/arm64) live on GHCR: ghcr.io/techdox/trove-server, ghcr.io/techdox/trove-agent-docker, ghcr.io/techdox/trove-agent-k8s, ghcr.io/techdox/trove-agent-proxmox. Static binaries for everything (including the bare-metal agent) are on the releases page.

How it works

  docker host          k8s cluster         proxmox            nas (systemd)
 ┌────────────┐      ┌────────────┐      ┌────────────┐      ┌────────────┐
 │ agent      │      │ agent      │      │ agent      │      │ agent      │
 └─────┬──────┘      └─────┬──────┘      └─────┬──────┘      └─────┬──────┘
       │    POST /api/v1/report (Bearer token, every 30s)          │
       └───────────────┬───┴──────────────┬────────────────────────┘
                       ▼                  ▼
                  ┌─────────────────────────────┐
                  │ trove-server                │
                  │  SQLite · REST · dashboard  │
                  └─────────────────────────────┘
  • Push model: agents POST full-state snapshots on an interval. The server never reaches into your infrastructure — homelab/NAT friendly.
  • Heartbeats: miss 3 intervals → agent (and its services) marked stale; miss 10 → offline. Thresholds scale with each agent's own interval.
  • Full-state reports are idempotent and tolerate lost pushes. Services that disappear are soft-removed and pruned after 24h.

Server install options

Docker Compose — the quickstart above; data lives in the trove-data volume.

Bare metal — grab trove-server from a release archive and use deploy/systemd/trove-server.service:

sudo install -m 0755 trove-server /usr/local/bin/
sudo cp deploy/systemd/trove-server.service /etc/systemd/system/
sudo systemctl enable --now trove-server

Go install (needs Go 1.26+):

go install github.com/techdox/trove/cmd/trove-server@latest

Configuration reference

trove-server
Variable Default Purpose
TROVE_ADDR :8080 Listen address.
TROVE_DB trove.db SQLite file path (containers default to /data/trove.db).
TROVE_FRESHNESS_ENABLED true false disables image-freshness checking.
TROVE_FRESHNESS_INTERVAL 5m How often to scan for images due a check.
TROVE_FRESHNESS_TTL 6h How long a resolved digest counts as fresh before rechecking.
TROVE_REGISTRY_AUTHS (unset) Credentials for private registries — see below.
TROVE_EVENT_RETENTION 720h How long events (activity feed / alert stream) are kept.
TROVE_REMOVED_RETENTION 24h How long removed services linger before being purged.
TROVE_ALERT_* / TROVE_SMTP_* (unset) Notification channels & SMTP — see docs/alerts.md.
TROVE_DIGEST daily@08:00* Digest schedule; *only takes effect once TROVE_SMTP_* is set — see docs/alerts.md.
TROVE_BOOTSTRAP_AGENT / TROVE_BOOTSTRAP_TOKEN (unset) Seed one agent at startup (used by the quickstart compose).

Private registry / Docker Hub credentials for freshness checks:

TROVE_REGISTRY_AUTHS='{"docker.io":{"username":"me","password":"dckr_pat_..."},"gitea.example.com":{"username":"me","password":"..."}}'

Docker Hub's anonymous rate limits are generous for Trove's batched, cached checks at homelab scale, but if you run many distinct Hub images, adding a (free) Hub account raises the ceiling.

Agents — common to all
Variable Default Purpose
TROVE_SERVER_URL (required) Base URL of the server.
TROVE_TOKEN (required) Bearer token from trove-server agent create.
TROVE_INTERVAL 30s Push interval (30s, 1m, or bare seconds 30).
TROVE_AGENT_NAME hostname Informational; not used for the dashboard display name (see below). For the bare-metal agent specifically, it (or the OS hostname) becomes the reported host name.

The name an agent appears under on the dashboard is the one you chose in trove-server agent create <name> — not TROVE_AGENT_NAME. Platform-specific settings are covered in each agent guide.

Managing agents
trove-server agent create <name>    # mint a token (shown once, stored hashed)
trove-server agent list             # names, platform, status, last seen
trove-server agent delete <name>    # remove an agent and all its data
trove-server alert test             # push a test notification through configured channels

API

Method & path Auth Purpose
POST /api/v1/report Bearer Agent pushes a full-state report.
GET /api/v1/services none Services grouped by host (dashboard data).
GET /api/v1/agents none Agents with derived heartbeat status.
GET /api/v1/events none Recent state-change events (?limit=).
GET /healthz none Liveness + database reachability.

The wire contract lives in pkg/model — the one package agents import. Building an agent for a new platform means implementing one interface; see CONTRIBUTING.md.

Security model

  • Agent ingest is authenticated with per-agent bearer tokens (256-bit random, stored only as SHA-256 hashes). Revoke by deleting the agent.
  • The dashboard and read APIs have no authentication in this phase. Treat the server like any internal tool: trusted network only, or front it with an authenticating reverse proxy. Native OIDC is on the roadmap.
  • Agents cannot change anything on the platforms they watch — read-only is enforced in code, not convention. Details in SECURITY.md.

Upgrades & backup

  • Upgrade: pull the new image (or binary) and restart. Schema migrations run automatically on startup; agents and server tolerate version skew within a minor version.
  • Backup: everything is one SQLite file (trove.db / the trove-data volume). Copy it while the server is stopped, or use sqlite3 ... ".backup" live. Trove state is rebuildable anyway — agents repopulate the catalog within one interval; you'd lose only event history.

Building from source

git clone https://github.com/techdox/trove.git && cd trove
make native   # all binaries for your host platform → bin/
make build    # cross-compile linux amd64+arm64
make test     # go test ./...
docker compose up --build   # contributor dev stack

Pure Go, no CGO, no frontend build step — the dashboard is vanilla JS embedded into the server binary.

Roadmap & contributing

Planned next: OIDC / dashboard auth, Helm chart, cert-expiry monitoring — see ROADMAP.md for the reasoning and sequencing. Contributions welcome: start with CONTRIBUTING.md.

License

MIT © Techdox

Directories

Path Synopsis
cmd
trove-agent-docker command
Command trove-agent-docker discovers containers on a Docker host and pushes full-state reports to a Trove server on an interval.
Command trove-agent-docker discovers containers on a Docker host and pushes full-state reports to a Trove server on an interval.
trove-agent-k8s command
Command trove-agent-k8s discovers workloads in a Kubernetes cluster and pushes full-state reports to a Trove server.
Command trove-agent-k8s discovers workloads in a Kubernetes cluster and pushes full-state reports to a Trove server.
trove-agent-local command
Command trove-agent-local discovers systemd service units on a Linux host and pushes full-state reports to a Trove server.
Command trove-agent-local discovers systemd service units on a Linux host and pushes full-state reports to a Trove server.
trove-agent-proxmox command
Command trove-agent-proxmox discovers VMs and LXC containers across a Proxmox VE cluster and pushes full-state reports (one per node) to a Trove server.
Command trove-agent-proxmox discovers VMs and LXC containers across a Proxmox VE cluster and pushes full-state reports (one per node) to a Trove server.
trove-server command
Command trove-server is the Trove server: it ingests agent reports, serves the read-only dashboard + APIs, and provides an agent-token CLI.
Command trove-server is the Trove server: it ingests agent reports, serves the read-only dashboard + APIs, and provides an agent-token CLI.
internal
agentkit
Package agentkit holds the machinery every Trove agent shares: common config loading, the report push client, and the collect-and-push loop.
Package agentkit holds the machinery every Trove agent shares: common config loading, the report push client, and the collect-and-push loop.
alert
Package alert turns Trove's event stream into outbound notifications: instant pushes (generic webhook, Discord, ntfy) driven by a cursor over the events table, plus a scheduled email digest.
Package alert turns Trove's event stream into outbound notifications: instant pushes (generic webhook, Discord, ntfy) driven by a cursor over the events table, plus a scheduled email digest.
registry
Package registry resolves the latest manifest digest for an image tag from a container registry, so the server can tell whether a running image is stale.
Package registry resolves the latest manifest digest for an image tag from a container registry, so the server can tell whether a running image is stale.
server
Package server wires the HTTP surface for the Trove server: the agent ingest endpoint (bearer-authenticated), the read-only dashboard APIs, the embedded SPA, and the background staleness ticker.
Package server wires the HTTP surface for the Trove server: the agent ingest endpoint (bearer-authenticated), the read-only dashboard APIs, the embedded SPA, and the background staleness ticker.
staleness
Package staleness holds the pure heartbeat-evaluation logic: given when an agent was last seen and its push interval, decide whether it is ok, stale, or offline.
Package staleness holds the pure heartbeat-evaluation logic: given when an agent was last seen and its push interval, decide whether it is ok, stale, or offline.
store
Package store is the SQLite persistence layer for the Trove server.
Package store is the SQLite persistence layer for the Trove server.
pkg
model
Package model defines the wire contract shared between Trove agents and the Trove server.
Package model defines the wire contract shared between Trove agents and the Trove server.
Package web embeds the Trove dashboard SPA so the server ships as a single binary.
Package web embeds the Trove dashboard SPA so the server ships as a single binary.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL