Grounded Docs
v0.2.0 · alpha Download Changelog GitHub
>_ docs / operations / Self-hosting
§ 04 Operations

Self-hosting

Grounded is built to self-host: no cloud, no account, no telemetry. Run it as a Docker container, a systemd service or a Windows scheduled task, keep its cabinet on disk, and scale from one SQLite file to Postgres when you need to — without changing how anything behaves.

// How it runs

Backends #

grounded install materializes one of these backends, all driving the same service and cabinet:

  • Docker — a container labelled com.grounded.managed, restart=unless-stopped, with ~/.grounded (config) and ~/Grounded/Cabinet (data) mounted into it. An install from before the split keeps its single ~/.grounded mount at /cabinet, so reinstalling never loses track of its data. Pass --image to run a published image instead of building locally.
  • systemd — a user unit (~/.config/systemd/user/grounded.service) or a system unit (/etc/systemd/system/), Restart=always.
  • Windows scheduled task — a per-user task named Grounded; no admin rights, no Docker. This is what Grounded Companion manages.

Manage either with grounded start / stop / restart / logs / status — it reads install.json to know which backend it created.

// The one config file

config.toml #

~/.grounded/config.toml is the source of truth for storage, embeddings, recall tuning, and ingest. It's portable — no absolute paths baked in. Defaults:

config.toml ~/.grounded
[storage]
adapter = "sqlite" # "sqlite" | "postgres"
path = "~/Grounded/Cabinet/grounded.db" # the default; never written
[embeddings]
provider = "ollama" # "ollama" | "local" | "openai" | "none"
baseUrl = "http://localhost:11434"
model = "nomic-embed-text"
dims = 768
[recall]
rrfK = 60
tieBreakOrder = ["doc", "fact", "session"]
[recall.sourceCaps]
fact = 10; session = 10; doc = 10
[recall.laneShare] # share of `limit`, multi-source only
fact = 0.25; session = 0.5; doc = 1
[recall.boosts]
pinned = 1.0; importance = 0.5
recencyHalfLifeDays = 30; activeStatus = 1.25
scopeAffinity = 1.5; scopeMismatch = 0.8
scopeSpecificity = 1.0
[ingest]
stripPrivate = true; stripFrontmatter = true
chunkChars = 1200; chunkOverlap = 150

Every key under [recall] — the boosts, the scope tiers, the lane shares, the tiebreak — is explained in Recall & ranking. Set any boost to 1 to turn that pressure off.

// Overrides

Environment #

Environment variables override config.toml at load time — handy for containers and units.

VariableSets
GROUNDED_HOMEConfig home (default ~/.grounded). Data lives in ~/Grounded/Cabinet; any other folder is self-contained, with data in its cabinet/.
GROUNDED_STORAGE_ADAPTERsqlite or postgres.
GROUNDED_DB_URLPostgres connection URL.
GROUNDED_EMBED_PROVIDERollama / local / openai / none. local is what the Embeddings add-on sets.
GROUNDED_EMBED_DEVICEcpu keeps embeddings off the GPU.
GROUNDED_EMBED_BASEURLEmbedding endpoint base URL.
GROUNDED_EMBED_MODELEmbedding model.
GROUNDED_OPENAI_API_KEYOpenAI key (openai provider).
GROUNDED_API_PORTListen port (default 7437).
GROUNDED_API_HOSTListen host (default 127.0.0.1).
GROUNDED_API_TOKENRequire a bearer token on the API.
// When one file isn't enough

The Postgres adapter #

For scale or a shared homelab, switch storage.adapter to postgres and set storage.url. Grounded uses pgvector for the vector lane and a generated tsvector for full-text, in a grounded schema (configurable). It self-migrates its schema on first open, and recall behaves identically to SQLite — the adapters are interchangeable by contract. Switching models or adapters is an explicit re-embed, never silent.

// It's just files

Backup & restore #

On the default adapter the entire cabinet is a directory you can copy: the SQLite database at ~/Grounded/Cabinet/grounded.db (%USERPROFILE%\Grounded\Cabinet on Windows), plus ~/.grounded/config.toml. Snapshot it with ordinary tools; restore by dropping it back in place and starting the service. Nothing important is trapped inside an opaque index — every row is recoverable from the cabinet.

// Is it well?

Health #

GET /health (always unauthenticated) reports the installed version, the storage adapter and location, the embedding provider / model / dims / device, which add-ons are on, the Databox state, and counts of facts, sessions, doc chunks, and distinct documents. It's what grounded status, the console, Companion's update check, and container health checks all read.