Host-scoped Config
config.toml is fleet-wide by default: every key applies to every host. The reserved [hosts.<name>] table scopes keys to one host — for that host’s runs, its entries override the top level in preflight validation and in the variables passed to Ansible.
domain = "example.com"headscale_subdomain = "hs"blocky_subdomain = "dns"
[hosts.agent-box]headscale_subdomain = "" # this host does not serve headscaleblocky_subdomain = "" # nor blockyssh_port = "2244" # nor the fleet's SSH port<name> matches the host’s hosts.toml entry. Tables for names no host carries are inert.
Blank overrides withdraw a role
Section titled “Blank overrides withdraw a role”infrastructure.yml gates headscale and blocky on their *_subdomain keys. A blank override makes the gate read unset for that host:
Run against agent-box |
Result |
|---|---|
untagged infrastructure |
headscale and blocky skipped, everything else runs |
-t headscale / -t blocky |
preflight fails naming the blanked key |
Naming a gated role’s tag asserts it runs, so asking for it on a host that withdrew the key is an error, not a silent no-op.
What stays top-level
Section titled “What stays top-level”An <app>_subdomain is the app’s record name in the fleet’s DNS zone — fleet identity, read by DNS discovery from the top level. Scope it per host only to withdraw the role (blank); give divergent values per host only for keys that are genuinely per-host (ports, <app>_tailscale_ip).
<app>_zone is the exception: it must be host-scoped, and preflight refuses it at the top level. A host’s zones decide which ACME tokens land on its Caddy. See Forgejo’s own DNS zone.
Existing multi-host fleets
Section titled “Existing multi-host fleets”auberge headscale commands default to the one host whose config answers headscale_subdomain. While several hosts answer (a fleet-wide key and no blanks), you get the interactive picker — blank the gate on non-serving hosts to regain the non-interactive default.
Guardrails
Section titled “Guardrails”- A
[hosts.<name>]table naming no known host fails preflight — a typo would otherwise silently hand the host every fleet-wide answer. - An override whose
!commandreference fails aborts the run instead of falling back to the fleet-wide value. restic_*keys are read fleet-wide bybackup push/verify/prune; scoping them per host is not supported.auberge host renamemoves the host’s table with it.
Editing
Section titled “Editing”auberge config set hosts.<name>.<key> <value> writes one key into [hosts.<name>], creating the table if absent. auberge config remove hosts.<name>.<key> removes it, and drops the table once empty. auberge config get hosts.<name>.<key> reads the override alone, never the fleet-wide value behind it. Every other dotted name is refused, as is the bare hosts name. auberge config list shows host-scoped entries as hosts.<name>.<key> rows, secrets redacted.
auberge config set hosts.agent-box.headscale_subdomain ""set and remove rewrite the whole file, dropping comments and key order. To keep them, edit the file instead: auberge config edit.