Configure a Platform instance¶
Every Nerthus.Platform instance, whatever roles it runs, reads its settings from one file, one set of
NERTHUS_* environment variables and the command's flags, in one order, through one module. This
page is every key there is and how an instance resolves it.
The order applies per key, not per file: a file that sets database.port and an environment
that sets database.url give you both. nerthus config show --effective prints each resolved value
beside the source that answered it, which is where every configuration question starts.
Which file is read¶
The first of these that exists:
--config <path>on the command. A path that does not exist is an error, not a fall-back.NERTHUS_CONFIG, with the same rule../nerthus.tomlin the working directory.<config dir>/nerthus.toml, where the configuration directory is--config-dir, thenNERTHUS_CONFIG_DIR, then~/.config/nerthus.
A clone's own file beats the one in the configuration directory. No file at all is supported: a
container can configure itself from NERTHUS_* alone.
Make one¶
writes ~/.config/nerthus/nerthus.toml, creates the data directory and the instance's age identity.
Running it again writes nothing and says so; change a setting by editing the file.
| Flag | Default | What it does |
|---|---|---|
--site <name> |
required | The site's display name. The id beside it is a fresh UUIDv7. |
--config-dir <path> |
~/.config/nerthus |
Where nerthus.toml and the age identity live. |
--data-dir <path> |
~/.local/share/nerthus |
The instance's own directory. |
--env prod\|dev\|staging |
dev |
The site's environment. |
--kind site\|client\|isolated |
site |
What this instance is. |
--roles <list> |
none written | Roles to write into the file. |
--json |
off | Print the result as JSON. |
The keys¶
A key the schema does not declare is refused, and the message names it and the nearest key that does exist.
| Key | Type | Default | Environment | Meaning |
|---|---|---|---|---|
data_dir |
path | ~/.local/share/nerthus |
NERTHUS_DATA_DIR |
The cluster, the corpus clones, everything the instance owns. |
roles |
list or string | none | NERTHUS_ROLES |
Roles this process runs; "all" expands to every one. No default: an instance told nothing refuses to serve. |
site.id |
UUIDv7 | minted by init |
NERTHUS_SITE_ID |
What events, grants, rulings and audit rows name. |
site.name |
string | unset | NERTHUS_SITE_NAME |
A display name. May change; the id never does. |
site.env |
prod\|dev\|staging |
dev |
NERTHUS_SITE_ENV |
The site's environment. |
site.image |
image reference | unset | NERTHUS_SITE_IMAGE |
The image this site runs. Required at prod; see below. |
instance.kind |
site\|client\|isolated |
site |
NERTHUS_INSTANCE_KIND |
See Instance kinds. |
database.url |
string | unset | NERTHUS_DATABASE_URL |
Set only when the site uses a Postgres it does not run; the bundled server is then never started. |
database.port |
integer | 5432 |
NERTHUS_DB_PORT |
The port the bundled server binds. |
database.bind |
list or comma string | ["127.0.0.1"] |
NERTHUS_DB_BIND |
Addresses, or interface names ("wg0") resolved on the host. |
listen.host |
string | 0.0.0.0 |
NERTHUS_LISTEN_HOST |
Where the read role answers. Loopback would make a container unreachable. |
listen.port |
integer | 8080 |
NERTHUS_LISTEN_PORT |
The read role's port. |
backup.endpoint |
URL | unset | NERTHUS_BACKUP_ENDPOINT |
The S3-compatible endpoint backups go to. Unset means this site takes none. |
backup.bucket |
string | unset | NERTHUS_BACKUP_BUCKET |
The bucket in it. |
backup.region |
string | auto |
NERTHUS_BACKUP_REGION |
auto is R2's own name; another S3-compatible store wants a region name. |
backup.prefix |
string | empty | NERTHUS_BACKUP_PREFIX |
Everything this site writes lives under it, so one bucket may hold several sites. |
backup.retain_days |
integer | 0 |
NERTHUS_BACKUP_RETAIN_DAYS |
How many days of backups a retention pass keeps. 0 deletes nothing. |
backup.r2_budget_bytes |
integer | 6442450944 (6 GiB) |
NERTHUS_BACKUP_R2_BUDGET_BYTES |
What this site may keep in the bucket. A backup that would pass it is refused. 0 means no budget. |
corpora.<key>.path |
path | unset | NERTHUS_CORPUS_<KEY>_PATH |
The clone this instance reads. |
corpora.<key>.remote |
string | unset | NERTHUS_CORPUS_<KEY>_REMOTE |
The remote it converges against. |
Corpora¶
A corpus <key> is one of lore, metadata, moderation, transcripts, annotations, works;
anything else is refused. Everything about a corpus that is the same on every site (its kind,
whether and how the write role publishes to it, the credential that reaches it, its fetch cadence,
its pair, and what a reader gets when the site holds no clone) is in the corpora manifest carried in
the package. A site's file says only where each clone is.
A path is a clone adopted where it is. A remote with no path is a clone the instance owns,
under <data_dir>/corpora/<key>. Neither means the instance does not carry that corpus. lore and
metadata are a pair: both remotes must name one pair of repositories, the same group and the same
suffix after the repozytorium-<name> stem, or the settings refuse to load.
nerthus corpus add lore --path ../repozytorium-fabularne-prodkopia
nerthus corpus list # the manifest beside this site's tables
nerthus corpus status # each clone's reached commit, whether it is dirty, why it is absent
corpus add refuses, before the file changes, anything the load would refuse.
The backup credential is not a key¶
backup.endpoint and backup.bucket are facts. The access key pair lives in the instance's sops
store as R2_ACCESS_KEY_ID and R2_SECRET_ACCESS_KEY, and nowhere else: no environment variable,
no configuration key. Back up and restore has the command that puts it
there.
What a production site must pin¶
site.env = "prod" refuses a site.image that is not pinned by digest, and refuses a tag of main
or latest even with a digest: an image is pinned only when a release tag built it, and production
never tracks main.
[site]
env = "prod"
image = "registry.gitlab.com/margonem/nerthus/it/nerthus.platform:v0.3.0@sha256:0123…"
Read it back¶
nerthus config show # the file as written
nerthus config show --effective # the resolved values, each with the source that won it
nerthus config show --effective --json
--effective also reports, on stderr, any NERTHUS_* variable in the environment that the package
reads nowhere. A mistyped variable (NERTHUS_DB_PORTT) does nothing at all, so it is reported; it
is not refused, because containers and CI jobs carry NERTHUS_* names the package does not own.
Instance kinds¶
instance.kind is configuration, never inferred from the roles.
| Kind | What it is | What it may not do |
|---|---|---|
site |
An instance carrying roles for a shared site. | — |
client |
Somebody's machine: a full local site that subscribes to a site. | Hold write or load for the site it subscribes to; be pushed into. |
isolated |
A client that subscribes to nothing: it clones corpora with its owner's own read access, derives locally, runs live, and exports drafts somebody else submits. |
Publish, subscribe or command. nerthus site enrol refuses it, and the write role over a corpus that has a remote is refused when the settings load. |
Reserved roles¶
live and bridge are in the role vocabulary and carry no behaviour yet. An instance holding one
starts and answers /health, and the answer names it:
nerthus doctor prints the same two facts: the instance kind, and which of its roles are reserved.