hyperhive — swarm options
services.hyperhive.swarm.authelia.package
authelia package to run in the container. Defaults to nixpkgs’s; override to pin a specific upstream.
Type: package
Default:
pkgs.authelia
Declared by:
services.hyperhive.swarm.authelia.bridgePackage
swarm-authelia-bridge package — the only process allowed to
write usersFile. Wired by default from this flake’s own
package set (see flake.nix); override to run a different
build.
Type: package
Default:
hyperhive.packages.${system}.swarm-authelia-bridge
Declared by:
services.hyperhive.swarm.authelia.bridgePort
TCP port swarm-authelia-bridge listens on, loopback-bound
(127.0.0.1:${bridgePort}) — one above authelia’s own default
port (9091), outside hyperhive’s other claimed ranges.
Reachable directly from this host’s other processes (this
container shares the host netns, same as authelia’s own port)
without going through the gateway — this is an internal
service-to-service endpoint, not something meant to be exposed
publicly.
Type: 16 bit unsigned integer; between 0 and 65535 (both inclusive)
Default:
9092
Declared by:
services.hyperhive.swarm.authelia.bridgeUrl
Where swarm-authelia-bridge answers, as seen from this
host — correct only when a caller (swarm-controller) also
runs on this host, the same co-location assumption
swarm.nix’s clientSecretFile documents for its own
cross-host case. null when this host doesn’t run
swarm-authelia at all.
A split-host swarm has no automated delivery for this address:
the operator points swarm-controller’s own option at wherever
this host has made the bridge reachable (a firewall rule, a
different bind address), the same manual-copy shape used
throughout this codebase’s other cross-host cases.
Type: null or string (read only)
Default:
if enable then "http://127.0.0.1:${bridgePort}" else null
Declared by:
services.hyperhive.swarm.authelia.domain
Public hostname for the SSO provider — the sub-domain shape the
forge and matrix already use, under the swarm’s domain because a
swarm has one SSO provider. Must be the name browsers
actually visit: it is the authelia_url the session cookie is
validated against.
⚠️ Unlike the forge and matrix names, this one carries no
migration pin: nothing depends on the previous
auth.${services.hyperhive.domain} yet, so it moves outright.
Type: string
Default:
"auth.${services.hyperhive.swarm.domain}"
Example:
"login.example.com"
Declared by:
services.hyperhive.swarm.authelia.hiveClientPrefix
Prefix of the OAuth2 client id minted for each hive in
services.hyperhive.swarm.hives — the client for hive alpha is
hive-alpha.
Read-only for the same reason as machine and unit: it is what
this module produces, published so a consumer does not carry a
second copy.
The consumer that matters is the queue’s auth-callout responder, which decides which hive a connection is by stripping this prefix off the introspected client id. Split the two spellings and every hive is denied — as a timeout, indistinguishable from a hive that simply has not reported.
Type: string (read only)
Default:
"hive-"
Declared by:
services.hyperhive.swarm.authelia.machine
Name of the nixos-container authelia runs in. Read-only: it is
what this module declares, published so callers of
systemctl -M and /var/lib/nixos-containers/<name> do not
have to hardcode it.
Type: string (read only)
Default:
"swarm-authelia"
Declared by:
services.hyperhive.swarm.authelia.metricsPort
TCP port authelia serves its Prometheus metrics on, bound to loopback. Upstream’s default, kept so an operator reading authelia’s documentation finds what they expect.
A separate port from port because it is a separate
listener with a different audience: the main one is proxied by
the gateway and reachable from the swarm, this one is scraped by
the collector on this host and by nothing else.
⚠️ Every swarm container shares the host network namespace, so two services defaulting to the same port do not conflict at build time — one simply loses at runtime, with nothing in any log. Check a new value against the others before changing this.
Note: Loopback means this endpoint is only reachable by a collector on the same host, so the scrape target is declared only when one is enabled here. Run the swarm’s collector elsewhere and authelia’s metrics are simply not collected — no error, and nothing in a log to say so. Making them reachable across hosts is a different piece of work: the endpoint would have to be published under a name, with a certificate and an audience.
Type: 16 bit unsigned integer; between 0 and 65535 (both inclusive)
Default:
9959
Declared by:
services.hyperhive.swarm.authelia.oidc.clients
OIDC relying parties this provider will issue tokens to. Declaring one turns the provider on; the default empty list leaves this module exactly as it was — a session provider and nothing else.
⚠️ There is deliberately no secret here. A client secret has
two holders in two containers (authelia keeps a hash, the
relying party the plaintext), and
services.authelia.instances.<n>.settings is rendered into the
nix store, which is world-readable and permanent. So this
option carries only the parts that are safe to evaluate: the
secret is minted on first boot and never passes through a nix
expression. See docs/swarm/ for what goes where.
Type: list of (submodule)
Default:
[ ]
Declared by:
services.hyperhive.swarm.authelia.oidc.clients.*.accessTokenSignedResponseAlg
Signing algorithm for this client’s access tokens.
null leaves authelia on its default, which issues an
opaque token (authelia_at_…) — a database handle that
carries no claims and means nothing to anyone but this
provider.
Set RS256 when the resource server verifies the token
itself rather than asking this provider about it: that
yields an RFC 9068 JWT (at+jwt) carrying aud, iss
and client_id, verifiable against /jwks.json with no
round trip.
⚠️ This is what makes a token readable by an OIDC-verifying consumer at all. A resource server given an opaque token is not misconfigured — it is structurally unable to verify it, and says so in terms that point at the verifier rather than at the token’s format.
Type: null or one of “none”, “RS256”
Default:
null
Example:
"RS256"
Declared by:
services.hyperhive.swarm.authelia.oidc.clients.*.audience
Audiences (aud) this client is permitted to request a
token for. Empty means it asks for none, which is the
right answer for a client whose resource server does not
distinguish callers.
⚠️ Registering an audience only permits it — the value
lands in a token when the client asks for it at the
token endpoint, and a client that does not send
audience= receives a token with aud: [] however
complete this list looks. Measured against authelia
4.39.20: the config reads exactly right and the resource
server rejects every token, because a config that grants
and a request that claims are two separate acts.
Requesting an audience that is not listed here is
refused with invalid_target, which is what makes this
usable as a boundary rather than a label: a client cannot
mint a token for a resource slot that is not its own.
Type: list of string
Default:
[ ]
Example:
[
"hive-alpha"
]
Declared by:
services.hyperhive.swarm.authelia.oidc.clients.*.bearerAuthz
Grant this client the authelia.bearer.authz scope, so it
may present its access token to authelia’s authz endpoint
and be authorised by an access_control rule — how a
scraper reaches a service published behind the gateway.
A named capability rather than a free-form scopes list,
for the same reason kind derives the rest: authelia
refuses some scope/grant combinations outright (openid
with client_credentials among them), and a list would
make those combinations expressible again. This admits the
one value that is legal here and nothing else.
Note: Setting this obliges two other options, and the assertions
below enforce it. Authelia checks the same thing, but only
in its preStart validator — which means a violation
builds and deploys cleanly and then fails to restart,
taking swarm SSO down. The assertions move that to
evaluation, where a wrong value costs nothing.
Type: boolean
Default:
false
Example:
true
Declared by:
services.hyperhive.swarm.authelia.oidc.clients.*.description
Human-readable name, shown on authelia’s consent screen. This is the string a person reads when deciding whether to hand an application their identity, so it should name the application rather than the protocol.
Type: string
Example:
"HyperHive forge"
Declared by:
services.hyperhive.swarm.authelia.oidc.clients.*.id
OAuth2 client id, as the relying party knows itself.
Type: string
Example:
"forgejo"
Declared by:
services.hyperhive.swarm.authelia.oidc.clients.*.kind
Whether a human logs in through this client, or a daemon authenticates as itself.
interactive is the authorization-code flow: a browser is
redirected, a person authenticates, the client receives an
id-token. machine is client_credentials: there is
nobody to redirect and no identity to assert but the
client’s own, so it receives an access token and no
id-token.
This is declared rather than inferred from an empty
redirectUris, because authelia permits only the grants a
client names — omitting grant_types yields
authorization-code alone, and a daemon then fails at the
token endpoint with unauthorized_client rather than at
evaluation.
Type: one of “interactive”, “machine”
Default:
"interactive"
Example:
"machine"
Declared by:
services.hyperhive.swarm.authelia.oidc.clients.*.redirectUris
Exact callback URLs the provider will redirect to. Matched literally by authelia — a trailing-slash difference is a rejected login, not a warning.
Meaningless for kind = "machine", which is asserted
rather than silently ignored.
Type: list of string
Default:
[ ]
Example:
[
"https://forge.example.com/user/oauth2/authelia/callback"
]
Declared by:
services.hyperhive.swarm.authelia.oidc.clients.*.tokenEndpointAuthMethod
How this client proves its identity at the token
endpoint. null leaves authelia on its own default
(client_secret_basic), which is what every client that
does not say otherwise gets.
Set it when the relying party’s implementation differs,
because authelia enforces the registered method rather
than accepting whatever arrives. tuwunel sends
client_secret_post, and against a client registered for
basic the result is a 401 from /api/oidc/token after
a successful consent — the login looks like it worked
right up to the last hop, and neither the redirect nor
the secret is at fault.
⚠️ null is NOT accepted on a client with bearerAuthz.
Measured against authelia 4.39.20: under that scope the
method must be stated: omitting it is refused with
must be configured as 'client_secret_basic', … but it's configured as an empty string. The sentence above is
true of an ordinary client and false of that one, which
is exactly how a reviewer reads this option and concludes
the assertion below is wrong.
Type: null or one of “client_secret_basic”, “client_secret_post”, “client_secret_jwt”, “private_key_jwt”, “none”
Default:
null
Example:
"client_secret_post"
Declared by:
services.hyperhive.swarm.authelia.oidc.hiveIdentities
Mint one machine client per hive in
services.hyperhive.swarm.hives, so each hive can
authenticate to swarm services as itself.
Defaults to whether the swarm message queue is enabled, because that is the first service that needs a hive to prove who it is. It is an option rather than a hard-coded condition so a second consumer — the swarm telemetry collector — can turn it on without the queue, and so a swarm that wants the identities provisioned ahead of either can say so.
The clients are inert until something authenticates with them: each is a client id and a secret sitting on this host. What delivers a secret to a hive that is not this host is a separate problem and deliberately not solved here.
Type: boolean
Default:
services.hyperhive.deploy.nats.enable
Declared by:
services.hyperhive.swarm.authelia.port
TCP port authelia listens on. 9091 is upstream’s default and sits outside hyperhive’s claimed ranges (dashboard 7000, forge 3000, matrix 8008, every agent in 8100…8999 via FNV-1a hash).
Type: 16 bit unsigned integer; between 0 and 65535 (both inclusive)
Default:
9091
Declared by:
services.hyperhive.swarm.authelia.unit
authelia’s systemd unit inside the container. Read-only, and derived from the instance name exactly like the unit itself.
Type: string (read only)
Default:
"authelia-swarm.service"
Declared by:
services.hyperhive.swarm.authelia.url
Base URL clients are sent to for authentication — the half of this module that exists on every hive, not just the one running the container.
Defaults to this host’s own instance only when this module is
the thing running it; in that case the URL is not a guess, it
is where this module just put the container. Otherwise null,
and a hive that federates with a swarm sets it explicitly to
wherever the swarm’s authelia lives. Null means “no SSO
configured” and consumers say so rather than inventing an
address — an endpoint baked in as a fallback is one that
resolves cleanly and points at the wrong machine.
Type: null or string
Default:
if enable then "https://${domain}" else null
Example:
"https://auth.example.com"
Declared by:
services.hyperhive.swarm.bao.domain
Name the store is reached on. A sibling of the swarm’s other
service names, not a child of any hive domain: an authority whose
nameConstraints permit one hive’s domain cannot issue for a sibling
of it, so the shape of this name decides which authorities could ever
sign for the store. That is a property of the name, not a choice of
issuer — this module makes no such choice.
Type: string
Default:
"bao.${services.hyperhive.swarm.domain}"
Declared by:
services.hyperhive.swarm.bao.machine
Container name. Read-only: the name appears in host paths and in
machinectl, so it is a fact other modules may read rather than a knob.
Type: string (read only)
Default:
"swarm-bao"
Declared by:
services.hyperhive.swarm.bao.port
TCP port the store listens on. Upstream’s own default, kept so an operator reading OpenBao documentation finds what they expect.
Swarm-wide because a client has to know it to reach the store, and
the same port on every listener: which addresses the store answers
on is the running host’s business
(services.hyperhive.deploy.bao.extraListenAddresses), but
which port it answers on is something the whole swarm agrees.
Type: 16 bit unsigned integer; between 0 and 65535 (both inclusive)
Default:
8200
Declared by:
services.hyperhive.swarm.ca.autoConfigure
Run the whole swarm CA on this one host: generate the swarm root when it is missing, and issue this hive’s CA under it.
services.hyperhive.deploy.singleHostSwarm turns this on as
part of the all-on-one-box mode. Set it here directly to run the
CA on a host that is not otherwise all-local.
Off by default, deliberately. A swarm’s services and its hives can live on different hosts, and this host has no way to tell whether it is the one holding the root — so the swarm CA is something an operator sets up, not something a host decides it is. Turn this on for an all-on-one-host deployment (dev boxes, single-hive swarms) and get the hierarchy for free.
With it off, both artifacts are operator-provided: the root
under stateDir, and this hive’s CA under
services.hyperhive.deploy.hive-controller.tls.stateDir. A hive
given neither keeps the self-signed CA it has always had — it
simply isn’t part of a swarm’s trust hierarchy, which is the
correct outcome for a hive nobody has federated yet.
Type: boolean
Default:
false
Example:
true
Declared by:
services.hyperhive.swarm.ca.servicesValidityDays
Validity window of the swarm-services sub-CA in days (~5y). Deliberately far shorter than the root’s: this CA is meant to be re-issued — adding a swarm service changes its name constraints and rotates it — so a long window buys nothing, and a short one keeps the rotation path exercised rather than theoretical.
Rotating it is cheap in the way rotating the root is not: it touches only the swarm-service vhosts, and no peer hive holds it as an anchor.
Type: signed integer
Default:
1825
Declared by:
services.hyperhive.swarm.ca.stateDir
Host directory holding the swarm root CA: root.pem (the
anchor, safe to distribute — copy it to this same path on every
other host in the swarm) and root-key.pem
(0600, the one file that must never reach the nix store or
another host). The directory itself is 0700: nothing reads
out of it but the hive CA issuance in hive-tls.nix.
Moving the swarm CA to its own host is a matter of moving this
directory and setting autoConfigure = false here.
Type: string
Default:
"/var/lib/swarm-ca"
Declared by:
services.hyperhive.swarm.ca.validityDays
Validity window of the swarm root CA in days (default ~30y).
Deliberately longer than services.hyperhive.deploy.hive-controller.tls.caValidityDays:
the root must outlive the hive CAs it issues, or those chains
expire out from under hives that are still perfectly happy with
their own intermediate. Rotating a root is the one operation in
this system with no partial-failure mode — it invalidates every
peer at once, paced by the slowest peer’s rebuild — so it is
never automatic and this window is meant to be uneventful.
Type: signed integer
Default:
10950
Declared by:
services.hyperhive.swarm.controller.package
swarm-controller package. Wired by default from this flake’s own
package set (see flake.nix); override to run a different build.
Type: package
Default:
hyperhive.packages.${system}.swarm-controller
Declared by:
services.hyperhive.swarm.controller.links
Quick links to swarm-wide services, surfaced by the swarm UI’s
links menu (GET /api/links). Same shape and same
zero-code-change-to-extend idea as hyperhive.dashboardLinks
(nix/agent-modules/dashboard-links.nix), one level up: rather
than one central hardcoded list, each service’s own module
contributes its own entry when it is actually enabled on this
host — swarm-authelia.nix, hive-matrix.nix and
hive-forge/default.nix all do — the same list-merge idiom
services.hyperhive.gateway.localNames already uses. A future
service module can push its own entry the same way, and an
operator can add arbitrary extra entries here directly; neither
needs a swarm-controller or swarm-ui change.
Only meaningful on the host that actually runs the controller —
entries contributed on any other host are computed but never
read. In a swarm that splits swarm-authelia/hive-matrix/
hive-forge across hosts other than the controller’s, this list
only reflects what is enabled locally; see each contributing
module’s own activation condition.
Type: list of (submodule)
Default:
[ ]
Example:
[ { label = "Wiki"; icon = "📖"; url = "https://wiki.example.com/"; } ]
Declared by:
services.hyperhive.swarm.controller.links.*.icon
Optional icon emoji or short glyph.
Type: string
Default:
""
Declared by:
services.hyperhive.swarm.controller.links.*.label
Display label for the link.
Type: string
Declared by:
services.hyperhive.swarm.controller.links.*.url
Full URL.
Type: string
Declared by:
services.hyperhive.swarm.controller.queue.natsUrl
Where the controller reaches the swarm queue.
Empty means unset, which the assertion below refuses — a controller with no queue is not a lighter controller.
singleHostSwarm fills this in with loopback, because
that address is only correct when the queue is on this host:
its container shares the host netns. That derivation lives with
the mode rather than here, so this option describes itself
rather than a deployment shape.
Type: string
Default:
""
Example:
"nats://queue.example.com:4222"
Declared by:
services.hyperhive.swarm.controller.queue.tokenEndpoint
The OIDC token endpoint the controller mints its own access token from.
Derived from swarm.authelia.url, which is the half of the
authelia module that exists on every host — so this is already
correct for a remote provider as long as that URL is set.
Type: string
Default:
"${swarm.authelia.url}/api/oidc/token"
Declared by:
services.hyperhive.swarm.controller.queueClientId
The OAuth2 client id the controller presents to the swarm queue. Read-only: it is what this module registers, published so the auth-callout responder can be told which client may read every hive’s key without repeating the string.
The responder decides that from a client id, and a client id it does not recognise is denied. A denial reaches a NATS client as a timeout rather than an error, and a controller that cannot read looks exactly like a swarm where no hive has reported yet — so a drift between these two spellings is invisible at the point it is introduced and misattributed everywhere it shows up.
Type: string (read only)
Default:
"swarm-controller"
Declared by:
services.hyperhive.swarm.controller.staleAfterSeconds
How old a hive’s last status snapshot may be before
GET /api/hives/status reports it as stale rather than fresh.
This is a statement about how often hives publish, not about how patient a reader is — set it above the publishing cadence or every hive reads stale between offers. It is an option and not a constant precisely because that cadence is a property of the deployment.
Freshness is derived when the endpoint is read, never stored, so changing this takes effect for the next request; no hive has to re-publish anything.
Type: positive integer, meaning >0
Default:
120
Declared by:
services.hyperhive.swarm.controller.swarmctlPackage
swarmctl package — the swarm operator’s CLI, installed on this
host alongside the daemon and wrapped with the paths it needs.
A separate option from package rather than a second binary in
the same derivation: the CLI runs as root and acts directly,
the daemon runs unprivileged and serves a socket, and pinning one
without the other is a thing an operator may legitimately want.
Type: package
Default:
hyperhive.packages.${system}.swarmctl
Declared by:
services.hyperhive.swarm.domain
DNS domain of the wider swarm this hive belongs to. Each hive
occupies its own sub-domain of it, which is why every entry in
services.hyperhive.swarm.hives defaults its domain to
<name>.<swarm.domain> — set this plus
services.hyperhive.hiveName, list the hives by name, and no
hive in the swarm states an address at all.
Required when services.hyperhive.enable, and deliberately
not defaulted: there is no fallback worth having. A guessed
swarm domain is a wrong hostname that evaluates cleanly and
deploys, which is worse than an eval failure telling an
operator to write down the one address their swarm answers to.
Upgrading past this costs one line, once.
Type: null or string
Default:
null
Example:
"darkest.space"
Declared by:
services.hyperhive.swarm.forge.package
Forgejo package to run inside the container. Defaults to
pkgs.forgejo (the latest release line) rather than the
nixpkgs-module default of pkgs.forgejo-lts, because LTS
lags far behind on schema and the DB easily ends up “newer
than the binary” if the operator ever ran a non-LTS forgejo
against the same state dir. Override to pkgs.forgejo-lts
if you actively want the slower release train.
Type: package
Default:
pkgs.forgejo
Declared by:
services.hyperhive.swarm.forge.domain
Public hostname for the forge. Doubles as both the forgejo
DOMAIN setting (clone URLs forgejo advertises) AND the
gateway vhost server-name when deploy.forgejo.behindGateway = true
(sub-domain routing — see docs/networking/gateway.md).
Defaults to forge.${services.hyperhive.swarm.domain} — the
swarm’s domain, not this hive’s, because a swarm runs one
forge that every hive in it talks to.
⚠️ A deployment that was running before this moved keeps its
current name by pinning it here:
forge.${services.hyperhive.domain}, which is exactly what
the old default rendered. Certificates follow either way: the
swarm-services sub-CA is name-constrained to the configured
names (see ./swarm-ca.nix), not to a fixed tree.
Set to a full hostname (git.example.com,
forge.internal.lan, etc.) for a bespoke vhost shape — the
full domain goes here, no separate sub-domain-label option.
Type: string
Default:
"forge.${services.hyperhive.swarm.domain}"
Example:
"git.example.com"
Declared by:
services.hyperhive.swarm.forge.httpPort
TCP port the forge serves HTTP on. Default 3000 sits outside hyperhive’s claimed ranges (dashboard 7000, every agent in 8100…8999 via FNV-1a hash). Change this if you already have another forgejo bound to 3000.
Type: 16 bit unsigned integer; between 0 and 65535 (both inclusive)
Default:
3000
Declared by:
services.hyperhive.swarm.forge.publicUrl
Browser-facing forge URL the dashboard uses to build clickable
forge links (the H0M3 Forge tile, per-agent-row forge links,
the approval-queue’s “review PR on forge” link) — sourced into
every agent container + hive-c0re as HIVE_FORGE_PUBLIC_URL.
Defaults to https://${cfg.domain} when deploy.forgejo.behindGateway = true (the gateway vhost is genuinely reachable at that URL)
and null otherwise. When null, the dashboard hides
forge links rather than guessing one — see
docs/web-ui/dashboard.md::H0M3 page for the rationale (a
link built from the operator’s own browser hostname + a
container port is only an accident away from wrong on any
deployment that isn’t plain localhost).
Set this explicitly if deploy.forgejo.behindGateway = false and the
forge is still reachable at a stable URL you want linked from
the dashboard (e.g. http://<lan-host>:${toString cfg.httpPort}
for an all-LAN deployment) — leaving it unset there means the
dashboard’s forge links are simply absent, not broken.
Type: null or string
Default:
if behindGateway then "https://${domain}" else null
Example:
"https://forge.example.com"
Declared by:
services.hyperhive.swarm.forge.rootUrl
Override the auto-derived forgejo ROOT_URL. When null
(default), ROOT_URL is derived from cfg.domain + gateway
state, including the scheme:
deploy.forgejo.behindGateway = true→https://${cfg.domain}/. The gateway always terminates TLS (self-signed is the implicit floor when nogateway.tls.certDir/ ACME is set), so the forge is always advertised over https. A non-canonicalgateway.httpsPortis appended as:<port>.deploy.forgejo.behindGateway = false→http://${cfg.domain}:${cfg.httpPort}/
The TLS scheme is derived automatically now, so you only need to
set this for a genuinely bespoke shape (e.g. an external reverse
proxy on a different host/path). Must end with / per forgejo’s
ROOT_URL contract.
Type: null or string
Default:
null
Example:
"https://forge.example.com/"
Declared by:
services.hyperhive.swarm.forge.sshPort
TCP port the forge’s built-in SSH server listens on. Kept off
22 so it doesn’t clash with the host’s openssh. Agents push
with ssh -p <sshPort> git@<domain>:<owner>/<repo>.git.
Type: 16 bit unsigned integer; between 0 and 65535 (both inclusive)
Default:
2222
Declared by:
services.hyperhive.swarm.forge.sso.clientId
OAuth2 client id this forge identifies itself with. Must match
the id of the corresponding entry in
services.hyperhive.swarm.authelia.oidc.clients.
Type: string
Default:
"forgejo"
Declared by:
services.hyperhive.swarm.grafana.package
Grafana package to run.
Type: package
Default:
pkgs.grafana
Declared by:
services.hyperhive.swarm.grafana.domain
Name the gateway serves this on. A sibling of the swarm’s other
service names, so the swarm-services sub-CA can issue for it — see
hive-tls.nix for why a service name being a sibling rather than a
child decides which CA may sign it.
⚠️ Changing this changes the OAuth redirect URI, which authelia matches exactly. Both sides move together because both derive from this option; an operator who pins one by hand breaks the login.
Type: string
Default:
"grafana.${services.hyperhive.swarm.domain}"
Declared by:
services.hyperhive.swarm.grafana.machine
Container name. Read-only: the name appears in host paths and in
machinectl, so it is a fact other modules may read rather than a
knob.
Type: string (read only)
Default:
"swarm-grafana"
Declared by:
services.hyperhive.swarm.grafana.metricsPort
Loopback port on which the gateway’s nginx re-serves Grafana’s
/metrics, and nothing else, so the swarm’s collector can scrape it.
⚠️ This is nginx’s port, not Grafana’s. Grafana still claims none —
see services.hyperhive.deploy.grafana.socketDir for why that
matters. A prometheus scrape target is a host:port, and it cannot
address a unix socket; rather than undo the socket decision, the one
endpoint a scraper needs gets a listener of its own.
Bound to loopback and unauthenticated, which is the same posture every
other entry in
services.hyperhive.swarm.otel.scrapeTargets has: those
targets are trusted by proximity rather than by credential.
Deliberately not the published grafana.<domain> vhost, which
would put an authorization decision in front of a scrape.
The number itself is arbitrary and free today;
state/eval-port-collisions.sh is what keeps it that way, since a
second claim on a port in this shared namespace produces no bind error
and nothing in any log.
Type: 16 bit unsigned integer; between 0 and 65535 (both inclusive)
Default:
9095
Declared by:
services.hyperhive.swarm.grafana.oidc.clientId
The authelia OIDC client id. Names the application rather than
the protocol, per the convention in
services.hyperhive.swarm.authelia.oidc.clients.
Type: string
Default:
"swarm-grafana"
Declared by:
services.hyperhive.swarm.grafana.oidc.role
Grafana org role every SSO user is assigned.
Admin by default, and that is a considered default rather than
a permissive one: the login form is disabled whenever SSO is
configured, so this is the only way anyone reaches Grafana —
a Viewer default would produce a swarm nobody can administer.
Passing authelia already means being an operator of this swarm;
its user store is the small, swarmctl-managed one.
Lower it if a swarm ever grows read-only operators, which is a one-line change here.
Type: one of “Viewer”, “Editor”, “Admin”
Default:
"Admin"
Example:
"Editor"
Declared by:
services.hyperhive.swarm.hives
Every hive in this swarm, keyed by hiveName — including this
host’s own hive. The same attrset is meant to be identical on
every host in the swarm, so it can be written once and shared;
services.hyperhive.hiveName is what makes a given host read it
as “me and four others” rather than “five peers”.
Each entry needs no fields at all in the conventional case: a
hive’s domain defaults to <name>.<swarm.domain>, so the whole
directory is usually a list of names.
It must contain an entry for hiveName, which is asserted — this
host’s own address is read out of it (it is where
services.hyperhive.domain derives from), and a hive that lists
everyone but itself would otherwise derive its own peer set as
everything and peer with itself.
Type: attribute set of (submodule)
Default:
{ }
Example:
{
edge = {
domain = "edge.elsewhere.example";
wireguardAddress = "10.100.0.2/32";
};
pr1ma = {
wireguardAddress = "10.100.0.1/32";
wireguardEndpoint = "203.0.113.1:51820";
};
}
Declared by:
services.hyperhive.swarm.hives.<name>.domain
Public DNS domain this hive occupies — used for
swarm-controller’s hive roster, agent identity
(qualified agent@domain labels), and Matrix federation
discovery.
Defaults to <name>.<swarm.domain>, the convention every
hive in a swarm follows, so a conventional directory is
names only. Set it for a hive that is addressed by
something else.
Type: string
Default:
"${name}.${services.hyperhive.swarm.domain}"
Example:
"lab.example.com"
Declared by:
services.hyperhive.swarm.hives.<name>.wireguardAddress
IP address (with prefix) of this hive’s host on the
WireGuard mesh. Used as the allowedIPs for its
WireGuard config entry (./swarm-wireguard.nix), so
intra-swarm traffic can route over the mesh address
rather than the public domain. Required to include
a hive in the mesh (entries missing this field are
silently excluded from wg-hive).
Type: null or string
Default:
null
Example:
"10.100.0.2/32"
Declared by:
services.hyperhive.swarm.hives.<name>.wireguardEndpoint
WireGuard endpoint for this hive in host:port form.
Null = this hive has no reachable endpoint, so the tunnel
is initiated from the other side.
Reads like a fact about the relationship and is not: it says whether this hive can be dialled, which every other hive in the swarm needs the same answer to.
Type: null or string
Default:
null
Example:
"203.0.113.1:51820"
Declared by:
services.hyperhive.swarm.hives.<name>.wireguardPublicKey
WireGuard public key for this hive’s host. Required when
services.hyperhive.deploy.wireguard.enable = true and
you want this hive reachable over the mesh. Null = TLS-
only peering (public internet, no mesh tunnel).
Type: null or string
Default:
null
Example:
"base64pubkey="
Declared by:
services.hyperhive.swarm.matrix.package
matrix-tuwunel package to run inside the container. Defaults
to nixpkgs’s pkgs.matrix-tuwunel. Override to pin a
specific upstream if you need an unreleased feature.
Type: package
Default:
pkgs.matrix-tuwunel
Declared by:
services.hyperhive.swarm.matrix.allowEncryption
Server-side switch for matrix end-to-end encryption — sets
tuwunel’s allow_encryption. Off by default: on the hive-internal
homeserver the operator already controls the transport, so server
E2EE adds key-management overhead (cross-signing, device
verification, undecryptable-message recovery) without a clear
threat-model win for the common single-hive case. Turn on when
agents join encrypted rooms on external / federated homeservers,
or when the operator wants message contents opaque to the
homeserver admin. Independent of the agent matrix client, which
always supports decryption so it can read encrypted rooms it is
invited to regardless of this flag; this option only governs
whether THIS homeserver permits room encryption.
Type: boolean
Default:
false
Declared by:
services.hyperhive.swarm.matrix.apiUrl
Client-server API base URL hive-c0re itself uses to
provision matrix (register agent users, create the hive space
and chat room, invite members). Distinct from the agent-facing
hyperhive.matrix.url, which is the gateway vhost handed to
each agent’s hive-matrix-daemon.
Defaults to the loopback listener only when this module is the
thing running tuwunel — in that case the address is not a
guess, it is where this module just put the container. Set it
explicitly (with enable = false) when the homeserver runs on
another machine; “everything on one host” is a special case of
the full deployment, not the assumption.
null means hive-c0re has no homeserver to provision against
and matrix provisioning no-ops. There is deliberately no
fallback compiled into the daemon: an address baked into the
binary is one that builds fine and then talks to the wrong
machine.
Type: null or string
Default:
if services.hyperhive.deploy.matrix.enable
then "http://127.0.0.1:${toString services.hyperhive.swarm.matrix.httpPort}"
else null
Example:
"https://matrix.example.com"
Declared by:
services.hyperhive.swarm.matrix.gatewayHost
Public hostname for the matrix homeserver behind the gateway.
Defaults to chat.${services.hyperhive.swarm.domain} — the
swarm’s domain, because a swarm runs one homeserver. Set to
null to skip the gateway vhost (tuwunel stays direct on
httpPort). See docs/networking/gateway.md for the vhost map + matrix
discovery flow, and the federation port-8448 caveat at the
bottom of that doc.
⚠️ gatewayHost and serverName are different things, and
they carry very different costs. gatewayHost is the API
listener hostname (where nginx proxies /_matrix/*) and is
free to change: it is a routing detail clients rediscover
through .well-known. serverName is the matrix-identifier
domain embedded irrevocably in every user and room id —
adopting a new one is a different homeserver, not a rename.
Both defaults now sit under the swarm domain, but only this
one is safe to move on a running deployment.
A deployment that was running before this moved keeps its
current name by pinning
matrix.${services.hyperhive.domain} here — exactly what the
old default rendered.
Type: null or string
Default:
"chat.${services.hyperhive.swarm.domain}"
Example:
"matrix.example.com"
Declared by:
services.hyperhive.swarm.matrix.gui.package
Static web client dist served at gatewayHost’s vhost
(chat.<swarm-domain> by default). Override
to swap fluffychat for hydrogen-web, cinny, element-web, or
an out-of-tree dist — any replacement is mounted at the
sub-domain root with the upstream-default <base href "/">,
no sub-path gymnastics needed.
Type: package
Default:
pkgs.fluffychat-web with a postInstall patch that adds
the three files flutter341.buildFlutterApplication skips.
Declared by:
services.hyperhive.swarm.matrix.httpPort
TCP port tuwunel serves the matrix client-server API on.
Default 8008 is the matrix-spec well-known port. Sits
outside hyperhive’s claimed ranges (dashboard 7000, every
agent in 8100…8999 via FNV-1a hash). Federation listens on
federationPort separately.
Type: 16 bit unsigned integer; between 0 and 65535 (both inclusive)
Default:
8008
Declared by:
services.hyperhive.swarm.matrix.serverName
Matrix server_name — the host part of every user ID
(@argus:<server_name>) and room ID minted on this
homeserver. CRITICAL: must be stable from day one because
it’s embedded irrevocably in the identifiers.
Defaults to services.hyperhive.swarm.domain (the bare swarm
domain), because a swarm runs one homeserver — tying its
identity to a single hive’s domain would make relocating the
container between hives look like a different homeserver.
Combined with the .well-known/matrix/{client,server} routes
the gateway serves at that domain, clients auto-discover the
actual matrix endpoint without needing a subdomain. Override
here only if you need a different server_name shape (e.g.
chat.example.org for a bespoke hostname).
Breaking change, and the one on this page that cannot be
undone by rebuilding. This default has now moved twice — from
matrix.${services.hyperhive.domain}, then to the bare hive
domain, and now to the swarm domain. Every existing homeserver
must pin whichever value it already minted ids under, e.g.
services.hyperhive.swarm.matrix.serverName =
config.services.hyperhive.domain; # or "matrix.${…domain}"
before rebuilding. Adopting a new server_name does not rename
the old users and rooms — it strands them, because their ids
still name a homeserver that no longer answers.
Type: null or string
Default:
null
Example:
"chat.example.org"
Declared by:
services.hyperhive.swarm.matrix.sso.clientId
OAuth2 client id this homeserver identifies itself with. Must
match the id of the corresponding entry in
services.hyperhive.swarm.authelia.oidc.clients.
The secret it pairs with is a host path, so it lives at
services.hyperhive.deploy.matrix.sso.clientSecretFile.
Type: string
Default:
"tuwunel"
Declared by:
services.hyperhive.swarm.name
Human-readable name of the wider swarm this hive belongs to.
Hives at different DNS domains can share a swarm name when
they federate together. Exposed to agents as
HYPERHIVE_SWARM_NAME; surfaced in the dashboard chrome and
per-agent system prompt when set.
Type: null or string
Default:
null
Example:
"constellat1on"
Declared by:
services.hyperhive.swarm.nats.authPackage
The auth-callout responder package.
⚠️ Named authPackage, not package, on purpose: this module
deliberately has no package option for the server itself
(see the note above — upstream’s services.nats resolves
pkgs.nats-server on its own), so a bare package here would
read as “the NATS package” and mean something else entirely.
Type: package
Default:
hyperhive.packages.${system}.swarm-nats-auth
Declared by:
services.hyperhive.swarm.nats.clientId
OAuth2 client id the queue’s authentication path identifies
itself with. Must match the id of the corresponding entry in
services.hyperhive.swarm.authelia.oidc.clients — which this
module contributes for you when both run on this host.
Type: string
Default:
"swarm-nats"
Declared by:
services.hyperhive.swarm.nats.metricsPort
Port the Prometheus exporter serves NATS’s metrics on, bound to loopback for the swarm collector to scrape.
⚠️ This and monitorPort are two more claims on a port
space every swarm container shares — they run in this container but
privateNetwork = false, so a collision with any other hyperhive
service is a runtime coin toss over which process gets the port,
with nothing in any log saying so. Both defaults are upstream’s
own (nats-server 8222, prometheus-nats-exporter 7777) and
neither is claimed elsewhere in this repo, checked when they were
added.
Type: 16 bit unsigned integer; between 0 and 65535 (both inclusive)
Default:
7777
Declared by:
services.hyperhive.swarm.nats.monitorPort
Port NATS serves its monitoring endpoint on, bound to loopback.
Not a metrics endpoint: the server has no Prometheus format of its
own. This serves /varz, /connz, /routez as JSON, and the
exporter below is what translates it — which is why enabling the
exporter without this produces a process that starts cleanly and
scrapes nothing.
⚠️ Loopback, and the exporter is the only intended reader. The
endpoint is unauthenticated and /connz names every connected
client, so the address it binds is the whole access control. Do
not widen it, and do not put it behind a gateway vhost expecting
that to add one.
Type: 16 bit unsigned integer; between 0 and 65535 (both inclusive)
Default:
8222
Declared by:
services.hyperhive.swarm.nats.port
TCP port the queue listens on. 4222 is upstream’s default and sits outside hyperhive’s claimed ranges (dashboard 7000, forge 3000, matrix 8008, every agent in 8100…8999 via FNV-1a hash).
Type: 16 bit unsigned integer; between 0 and 65535 (both inclusive)
Default:
4222
Declared by:
services.hyperhive.swarm.otel.clientId
OAuth2 client id this collector authenticates as. Published so
authelia’s access_control rules can name it without carrying a
second copy of the string, exactly as
services.hyperhive.swarm.authelia.hiveClientPrefix is published
for the queue’s responder.
Two spellings drifting apart is not a build failure: authelia refuses a rule naming an unregistered client in its startup validator, so the swarm’s SSO service fails to restart — long after the change that caused it evaluated cleanly.
Type: string (read only)
Default:
"swarm-collector"
Declared by:
services.hyperhive.swarm.otel.domain
Name the gateway serves this on. A sibling of the swarm’s other
service names, so the swarm-services sub-CA can issue for it — see
hive-tls.nix for why a service name being a sibling rather than a
child decides which CA may sign it.
This is what the hive tier’s exporter reaches — the hive
collector is a plain producer against this name exactly like every
other client of a swarm service, resolved locally by dnsmasq on a
co-located host and over the real network otherwise. There is no
separate loopback-vs-remote knob to get wrong: swarm-nats is the
deliberate exception to this pattern (its cross-hive reach is the
wireguard mesh, not the gateway), everything else in this swarm
addresses its siblings by name.
Type: string
Default:
"otel.${services.hyperhive.swarm.domain}"
Declared by:
services.hyperhive.swarm.otel.journaldUnits
systemd units whose journal this collector ships to the swarm’s log store. Nothing outside this list is collected.
Every module that defines a unit worth reading swarm-wide adds its own names here, rather than one list naming them all: a service that is not running contributes nothing, and a service added later arrives with its units already declared. A central list would be a second place that has to know which services exist, and it would go stale in the direction that hides a service’s logs rather than the one that shows too many.
Names are matched as journald _SYSTEMD_UNIT values, so an
in-container unit is named exactly as it is inside its container
— authelia, not container@swarm-authelia.
⚠️ A name that matches nothing is not an error anywhere. The unit simply never appears in the store, which looks the same as a service that had nothing to say.
Type: list of string
Default:
[ ]
Example:
[
"nginx"
]
Declared by:
services.hyperhive.swarm.otel.machine
Name of the nixos-container this collector runs in — also the
machinectl name, so other modules may read it rather than
repeating the literal.
Type: string (read only)
Default:
"swarm-otel"
Declared by:
services.hyperhive.swarm.otel.port
First port of this collector’s receiver range. Every hive in
services.hyperhive.swarm.hives gets its own
authenticated receiver — that is what makes the hive label
unforgeable — so the range is one port per hive, starting here, in
sorted-name order.
⚠️ Internal. No client is ever told a port: a hive reaches its own
receiver as https://${domain}/<hive>, and the gateway routes on
that path. So adding a hive, which renumbers the ones after it, is
harmless — nginx is rendered from this same evaluation and moves
with it.
⚠️ Deliberately not 4318, the OTLP/HTTP default, because the
hive tier already uses it (services.hyperhive.otel.collector.port)
and every swarm container shares the host’s network namespace. Two
listeners claiming one port on one host is not a build failure —
it is a runtime coin toss over which one gets it, with nothing in
any log saying so. The same collision cost a release when grafana
and the forge both defaulted to 3000. The assertions below check
the whole derived range against every port this module and the hive
tier declare, which is as far as a module can see.
Type: 16 bit unsigned integer; between 0 and 65535 (both inclusive)
Default:
4319
Declared by:
services.hyperhive.swarm.otel.producerName
The swarm-tier producer’s own component/path/authenticator name
— the same reserved literal this module’s collector components
(otlp/swarm, oidc/swarm, resource/swarm, metrics/swarm)
are already named after internally. Published as an option so a
sibling module (swarm-controller.nix) can address the receiver
by name — https://${domain}/${producerName}/ — instead of
repeating the string. Read-only for the same reason
clientId/machine/domain are: two spellings of a name that
has to match on both ends is a mismatch waiting to happen.
Type: string (read only)
Default:
"swarm"
Declared by:
services.hyperhive.swarm.otel.producerPort
Port the swarm tier’s own OTLP/HTTP receiver for a
swarm-level producer (swarm-controller’s vcs/jobq counters
today) listens on, at 127.0.0.1. Reached through the gateway at
https://${domain}/${producerName}/, same shape as a hive’s
own receiver — a swarm-level producer may not share a host with
this collector (mara, on the swarm-controller topology: “the
swarm services dont have to run on the same host as the swarm
controller”), so loopback-only reachability is not a supported
shape here any more than it is for a hive.
Authenticated by oidc/${producerName}, checking for the
audience services.hyperhive.swarm.controller.queueClientId
requests — not the per-hive hiveClientPrefix namespace, because
a swarm-level producer is explicitly not a hive (see that
option’s own doc comment). The swarm label this receiver’s
samples get is still the one the receiver’s own existence
establishes, same as before — there is no hive identity being
forged or attributed here, just a caller proving it is the one
principal allowed to push into this pipeline.
⚠️ Deliberately NOT derived from port + (number of hives): that
range grows every time a hive is added, and a fixed offset from
it would silently start colliding once the hive count caught up.
Kept as its own reserved value instead, and the assertion below
still catches a real collision (including one hive growth
eventually causes) rather than starting a collector that quietly
drops one receiver’s samples.
Type: 16 bit unsigned integer; between 0 and 65535 (both inclusive)
Default:
4390
Declared by:
services.hyperhive.swarm.otel.publishedScrapeTargets
Prometheus endpoints this collector scrapes by name, with a
credential, as <job name> = "<url>".
A service module declares its own entry, from its own module, the
same way it does for scrapeTargets — and the collector’s OAuth2
client derives its permitted audiences from these URLs, so a
target and the authorisation to reach it are one declaration.
Two lists that must agree would be a drift to maintain, and its
failure mode is the bad one: a target whose audience was forgotten
authenticates against nothing and reads as a scrape failure rather
than a config mistake.
⚠️ A full URL, not host:port. Authelia validates a bearer
token against the address being requested, so the string here is
also the audience the token is minted for; a near miss (a trailing
slash, http for https) presents as a valid token rejected at
the target, several layers from its cause.
⚠️ Deliberately separate from scrapeTargets. An entry there is
trusted because the scraper and the target share a host — that
option is loopback-and-unauthenticated by contract. An entry here
is trusted because it presents a credential. One shape for both
would leave a reader unable to tell which of those a given target
relies on.
Type: attribute set of string
Default:
{ }
Example:
{ forge = "https://forge.example.com/metrics"; }
Declared by:
services.hyperhive.swarm.otel.scrapeTargets
Prometheus exposition endpoints this collector scrapes, as
<job name> = "<host>:<port>".
A path and query may follow the port —
"127.0.0.1:8202/v1/sys/metrics?format=prometheus" — for an
exporter that does not serve /metrics. Both are optional and
omitted when absent, so a bare host:port is scraped exactly as
before.
A service declares its own entry, from its own module, under its
own enable. Do not assemble the list here: an entry then exists
only where the service that named it runs, so a target is never
declared on a host that does not serve it.
⚠️ That constrains the TARGET, not the SCRAPER, and the difference
is a silent gap. Nothing here puts the collector on the same host.
Services are co-located by default — swarm-required-services.nix
derives their enable flags from one lib.mkDefault — not by
construction, and an operator may split them.
When they are split the target is simply never scraped: the service’s host declares an entry no local collector reads, and the collector’s host never enabled that service so has no entry at all. No error, no eval failure, no warning.
No assertion can catch this. Two hosts are separate NixOS evaluations with no shared context, so neither can see what the other runs. A service that would be seriously wrong to lose should say so in its own contribution, because saying it is the only mechanism available.
Samples land in a swarm-level pipeline that stamps swarm and
never hive: a swarm service does not belong to a hive, and
hive stays a property of which authenticated receiver accepted a
push, not something a scrape can acquire.
Empty by default, in which case no scrape receiver, processor or pipeline is emitted at all — an enabled scraper with nothing to scrape is the inert configuration this option exists to avoid.
Type: attribute set of string
Default:
{ }
Example:
{ forgejo = "127.0.0.1:3000"; }
Declared by:
services.hyperhive.swarm.otel.telemetryPort
Port this collector serves its own metrics on — queue depth, refused and dropped samples, exporter failures. How you find out that telemetry is being lost, so it is worth keeping rather than switching off.
⚠️ Deliberately not 8889’s neighbour 8888, which is the
collector’s built-in default and therefore what the hive tier
already binds. Two collectors share a network namespace whenever
they are co-located, and unlike the OTLP port this one appears
nowhere in either config — it is a default inside the binary, so
nothing that compares configured ports can see the clash. The
second collector to start simply dies with
bind: address already in use.
Type: 16 bit unsigned integer; between 0 and 65535 (both inclusive)
Default:
8889
Declared by:
services.hyperhive.swarm.snapshotStore.address
Mesh address of the swarm’s snapshot store — the single
btrfs receive endpoint every hive in this swarm pushes agent
snapshots to. Bare IP, no prefix.
There is exactly one store per swarm, not one per peer: the receiver keys destinations by agent, so an agent that migrates between hives keeps a single unbroken incremental chain. Per-hive stores would split that chain in two, which is the case the store exists to serve.
Null means this swarm has no store configured, and pushing fails
saying so rather than guessing an address. Set it on every hive
that pushes; the receiving host separately sets
services.hyperhive.snapshotStore.enable.
Type: null or string
Default:
null
Example:
"10.100.0.1"
Declared by:
services.hyperhive.swarm.snapshotStore.port
TCP port the swarm’s snapshot store listens on. Must match the
receiving host’s services.hyperhive.snapshotStore.port.
Defaulted (unlike address) because it is a shared convention
both sides read from the same option docs — whereas an address
is deployment-specific and cannot be guessed.
Type: 16 bit unsigned integer; between 0 and 65535 (both inclusive)
Default:
51821
Declared by:
services.hyperhive.swarm.statusPublish.tokenEndpoint
The swarm IdP’s OAuth2 token endpoint. This hive mints a
client_credentials access token there and presents it when
connecting to the queue, which authenticates it as
hive-<hiveName> — the client
nix/host-modules/swarm-authelia.nix already declares for
every entry in services.hyperhive.swarm.hives.
Type: null or string
Default:
"${swarm.authelia.url}/api/oidc/token" when this host runs both the queue and the IdP, else null
Example:
"https://auth.example.com/api/oidc/token"
Declared by:
services.hyperhive.swarm.ui.package
Static build of the swarm UI. nginx serves this store path directly — there is no server-side component beyond the controller’s own API.
Wired by default from this flake’s own package set (see
flake.nix), the same way swarm.controller.package is. There
is deliberately no overlay in this project, so a
pkgs.swarm-ui default here would name an attribute that does
not exist on any real deployment.
Type: package
Default:
hyperhive.packages.${system}.swarm-ui
Declared by:
services.hyperhive.swarm.victorialogs.package
VictoriaLogs package to run.
Type: package
Default:
pkgs.victorialogs
Declared by:
services.hyperhive.swarm.victorialogs.domain
Name the gateway serves this on, behind the same authelia
auth_request gate as the swarm UI’s own vhost. A sibling of the
swarm’s other service names, so the swarm-services sub-CA can
issue for it — see hive-tls.nix for why a service name being a
sibling rather than a child decides which CA may sign it, and
swarm.nix’s serviceDomains' for where this name has to be
registered for that to actually happen.
Type: string
Default:
"logs.${services.hyperhive.swarm.domain}"
Declared by:
services.hyperhive.swarm.victorialogs.machine
Container name. Read-only: the name appears in host paths and in
machinectl, so it is a fact other modules may read rather than a
knob.
Type: string (read only)
Default:
"swarm-victorialogs"
Declared by:
services.hyperhive.swarm.victorialogs.port
Loopback port the store listens on. Upstream’s default, kept because there is no reason to move it and a familiar number is one less thing an operator has to look up.
⚠️ Every swarm container shares the host’s network namespace, so
this is a swarm-wide claim rather than a per-container one — two
modules picking the same number collide at runtime with no bind
error and nothing in any log. state/eval-port-collisions.sh
checks the class.
Type: 16 bit unsigned integer; between 0 and 65535 (both inclusive)
Default:
9428
Declared by:
services.hyperhive.swarm.victoriametrics.package
VictoriaMetrics package to run.
Type: package
Default:
pkgs.victoriametrics
Declared by:
services.hyperhive.swarm.victoriametrics.domain
Name the gateway serves this on. A sibling of the swarm’s other
service names, so the swarm-services sub-CA can issue for it — see
hive-tls.nix for why a service name being a sibling rather than a
child decides which CA may sign it.
Type: string
Default:
"metrics.${services.hyperhive.swarm.domain}"
Declared by:
services.hyperhive.swarm.victoriametrics.machine
Container name. Read-only: the name appears in host paths and in
machinectl, so it is a fact other modules may read rather than a
knob.
Type: string (read only)
Default:
"swarm-victoriametrics"
Declared by:
services.hyperhive.swarm.victoriametrics.port
Port VictoriaMetrics listens on, bound to loopback only (see below). Upstream’s own default, kept so an operator reading VictoriaMetrics documentation finds what they expect.
Type: 16 bit unsigned integer; between 0 and 65535 (both inclusive)
Default:
8428
Declared by: