The config.yaml file
config.yaml is a simple, high-level configuration. It is the source of truth for the network. The generator reads it and produces var/generated/*.nix, consumed by the framework.
The file has four sections :
| Section | Role |
|---|---|
network | Global parameters: domain, locale, VPN coordination. |
zones | Subnets: IP prefix, gateway, non-NixOS devices. |
users | Accounts, common to all zones. |
hosts | Machines to deploy. |
“network” section
Section titled ““network” section”This optional section defines the global parameters of our network.
network: domain: "domain.tld" # root DNS domain (services, VPN, certificates) default: locale: "fr_FR.UTF-8" # default locale for every host timezone: "Europe/Paris" # default timezone coordination: enable: true # enables VPN mesh (Headscale) hostname: "hcs" # short name of the coordination host domain: "headscale" # subdomain → headscale.domain.tld| Key | Role |
|---|---|
domain | Root DNS domain (services, Headscale, certificates). |
default.locale | Default values, possibly overridden by zone. |
default.timezone | Default values, possibly overridden by zone. |
coordination.enable | Enables VPN coordination. false → local zones only. |
coordination.hostname | Headscale host and subdomain. |
coordination.domain | Headscale host and subdomain. |
”zones” section
Section titled “”zones” section”A zone is a subnet (home LAN, guest network, remote site…).
Each zone has an IP /16 prefix, a gateway and, optionally, non-NixOS devices.
zones: main: description: "Main network" locale: "fr_FR.UTF-8" # optional (default: network.default.locale) timezone: "Europe/Paris" # optional ipPrefix: "10.0" # the zone uses 10.0.0.0/16 gateway: wan: interface: "enp1s0" # interface to Internet (required) lan: interfaces: ["enp2s0"] # internal interface(s) (required) vpn: ipv4: "10.0.0.1" # gateway VPN IP (after registration)| Key | Role |
|---|---|
description | Zone label. |
locale / timezone | Local overrides (otherwise network.default). |
ipPrefix | First two octets of an RFC1918 /16 (e.g. 10.0). |
gateway | Gateway configuration (see below). |
extraHosts | Non-NixOS devices resolved by name (see below). |
The gateway
Section titled “The gateway”| Key | Role |
|---|---|
wan.interface | Network interface to Internet (required). |
lan.interfaces | List of internal interfaces (required), integrated into the lan0 bridge. |
lan.dhcp-range | DHCP range (optional; default <prefix>.3.200,<prefix>.3.249,24h). |
vpn.ipv4 | Gateway VPN IP, to fill in after Headscale registration. |
Non-NixOS devices (extraHosts)
Section titled “Non-NixOS devices (extraHosts)”Phones, printers, IoT devices: resolved by name and fixed on DHCP.
The common key is merged into each zone (devices present everywhere).
zones: main: # ... extraHosts: printer: ip: "4.1" # suffix → 10.0.4.1 name: "Living room printer" mac: "aa:bb:cc:dd:ee:01" common: extraHosts: # added to ALL zones phone-alice: ip: "5.1" name: "Alice's phone" mac: "aa:bb:cc:dd:ee:02"Section “users”
Section titled “Section “users””Shared accounts across all zones. Each account receives a profile Home Manager and groups.
users: alice: uid: 1000 name: "Alice Martin" email: "alice@domain.tld" profile: "nix-admin" groups: ["zone-main", "global", "idm-admins"] bob: uid: 1001 name: "Bob Durand" profile: "normal" groups: ["zone-main"]| Key | Type | Role |
|---|---|---|
| (key) | Account identifier (login) ([a-z]…). | |
uid | integer | Stable numeric identifier (required). |
name | text | Display name (required). |
email | text | Email address (also used for SSO identity), defaults to <login>@<domain.tld>. |
profile | text | User profile (default minimal). |
groups | list | Installs the user on hosts with the same group. |
”hosts” section
Section titled “”hosts” section”hosts is a list of entries (- hostname: …). A machine can be declared in three ways depending on the need.
Static type: one host per entry
Section titled “Static type: one host per entry”One entry = one machine. The simplest and most common form.
hosts:
- hostname: "gw" name: "Main gateway" zone: "main:1.1" # fixed IP 10.0.1.1 → gateway profile: "gateway" tags: ["main"] features: ["monitoring-node"] services: adguardhome: homepage:
- hostname: "server" name: "Home server" zone: "main:1.2" # fixed IP 10.0.1.2 profile: "server" users: ["alice"] services: nextcloud: restic:Collection type: similar machines
Section titled “Collection type: similar machines”A common config + a sub-map hosts:: each member (key) inherits the group’s keys (profile, groups, features, tags, disko) and specifies its own name, zone, MAC address. The %s in the group’s hostname/name is replaced by the member’s key (and by its name).
hosts:
- hostname: "%s-laptop" # %s → member key name: "Portable de %s" # %s → member's name profile: "laptop" groups: ["zone-main"] hosts: alice: # → hostname "alice-laptop" name: "Alice" zone: "main:2.4" mac: "aa:bb:cc:dd:ee:10" bob: # → hostname "bob-laptop" name: "Bob" zone: "main:2.5" mac: "aa:bb:cc:dd:ee:11"Range type: identical machines
Section titled “Range type: identical machines”Generates N identical hosts numbered sequentially. range: [start, end] (inclusive bounds). Template tokens (similar to printf substitutions 🡕) are replaced by the index :
| Token | Effect | Example (i=3) |
|---|---|---|
%d or %s | The index | vm-%d → vm-3 |
%'02s | Padded index (char + width) | vm-%'02s → vm-03 |
hosts:
- hostname: "desktop-%'02s" # desktop-01 … desktop-04 name: "Guest workstation n°%'02s" zone: "main:11.%d" # 10.0.11.1 … 10.0.11.4 profile: "desktop" range: [1, 4] groups: ["zone-main"] features: ["nfs-client"] mac: # MAC by index 1: "aa:bb:cc:dd:ee:21" 2: "aa:bb:cc:dd:ee:22" 3: "aa:bb:cc:dd:ee:23" 4: "aa:bb:cc:dd:ee:24"Key list
Section titled “Key list”| Key | Type | Role |
|---|---|---|
hostname | text | DNS identifier (required); templates %s/%d/%'02s. |
name | text | Readable name (required). |
profile | text | Host profile (gateway, server, desktop, laptop, hcs…). |
zone | text | Zone and IP (see below). |
ipv4 | map | External host: external (public IP) + internal (VPN IP). |
users | list | Logins authorized to open a session. |
groups | list | Host groups (add corresponding members). |
tags | list | Colmena tags (just apply @tag). |
features | list | Non-service flags (see below). |
services | map | Enabled services (see below). |
mac | text/map | Internal interface MAC (static), map by index (range). |
aliases | list | Additional DNS names. |
arch | text | Architecture (default x86_64-linux). |
disko | map | Disk scheme (see below). |
range | list | [start, end] for a range. |
hosts | map | Members (collection) or per-index overrides (range). |
Assigning a zone
Section titled “Assigning a zone”The zone key sets the network membership and the IP address :
| Form | Effect |
|---|---|
zone: "main:1.2" | Fixed IP <ipPrefix>.1.2 (e.g. 10.1.1.2 in zone main in 10.1). |
zone: "main:11.%d" | Fixed IP with range index (e.g. 10.1.11.1, 10.1.11.2…). |
zone: "main" | Dynamic address (DHCP) in the zone. |
An external host (the HCS) has no zone but an ipv4 block :
- hostname: "hcs" name: "Coordination" profile: "hcs" ipv4: external: "203.0.113.26" # public IP (external zone) internal: "10.0.0.2" # IP in the VPNAssigning features
Section titled “Assigning features”The features key enables specific behaviors or features.
A :<zone> suffix targets a specific zone (otherwise the host’s zone is used).
Examples:
# Machine under supervision (monitoring-node)# and NFS client (a server must exist in the zone)features: ["monitoring-node", "nfs-client"]
# Machine supervised by the "main" zonefeatures: ["monitoring-node:main"]Available features:
monitoring-node: the host exposes its metrics (node-exporter) to the zone’s monitoring.nfs-client: the host mounts shares from the zone’snfsserver (a server must exist in the zone).
Declaring services
Section titled “Declaring services”The services key contains a collection of services to be automatically installed on
the host. Values are optional and allow service customization.
services: immich: title: "Photos" description: "My photos & videos" domain: "photos" # sub-domain global: true # → https://photos.domain.tld (public) nextcloud: domain: "cloud" # → cloud.<zone>.domain.tld (non global) restic: # default values| Field | Role |
|---|---|
| (key) | Service to enable (e.g. immich). |
title | Name displayed on the portal. |
description | Subtitle on the portal. |
domain | Sub-domain (default: service name). |
global | Exposes publicly via the HCS: <domain>.domain.tld, without the zone. |
icon | Portal icon. |
Declaring partitioning
Section titled “Declaring partitioning”The disko key describes partitioning for automatic installation.
profiledesignates a(usr|dnf)/hosts/disko/<profile>.nixfile.devicesmaps the profile’s named disks to actual devices.
disko: profile: "btrfs-1-disk" devices: main: "/dev/nvme0n1"Useful links
Section titled “Useful links”For the full machine installation walkthrough, see Initial installation.