Getting Started
Prerequisites
Section titled “Prerequisites”- Nix with flakes enabled
Quick start
Section titled “Quick start”nix flake init -t github:vic/nest#fleet-demoThis gives you a complete multi-environment example. To understand it from first principles, read on.
A minimal example
Section titled “A minimal example”-
Add nest to your flake inputs
flake.nix inputs.nest.url = "github:vic/nest"; -
Define a host entity trait
The
hosttrait is an entity trait — it has aclassthat produces anixosSystem:nest.trait.host.class.nixos =select: cfg:nixpkgs.lib.nixosSystem {system = select.node.system;modules = [ cfg ];};select.nodeis the matched node (the host).cfgis the merged NixOS config from all matching rules. -
Declare a node in the DOM
nest.prod.system = "x86_64-linux";nest.prod.web = {is = [ nest.host ];system = "x86_64-linux";};nest.prod.webdeclares a node namedwebwith traithost. Theprodnamespace passessystemdown, but the node also declares it explicitly here. -
Write a rule
nest.rules = [{is = nest.host;nixos = {networking.hostName = "web";nix.settings.experimental-features = [ "nix-command" "flakes" ];};}];Every node matching
nest.hostgets these NixOS options. -
Access the output
Nest produces
nixosConfigurationsby routingbyClass.nixosto the standard flake output:flake.nixosConfigurations = config.flake.nest.evalResult.byClass.nixos;nixosConfigurations.webis a readynixosSystem.
What just happened
Section titled “What just happened”Nest’s evaluation for the web node:
is = [nest.host]— one trait, no dependencies to expand- No
neededByrules match - No
synthdefined - Rule
{ is = nest.host; nixos = … }matches —__mergedCfg.nixos = { networking.hostName = "web"; … } - No children to collect from
classFns.nixos select cfg=nixosSystem { system = "x86_64-linux"; modules = [cfg]; }— done
Adding trait dependencies
Section titled “Adding trait dependencies”Now add nginx and ssh via a server trait:
nest.trait.nginx = { };nest.trait.ssh = { };
nest.trait.server.needs = [ nest.nginx nest.ssh ];nest.trait.web.needs = [ nest.server ];
nest.prod.web = { is = [ nest.host nest.web ]; system = "x86_64-linux";};
nest.rules = [ { is = nest.host; nixos.networking.hostName = "web"; } { is = nest.nginx; nixos.services.nginx.enable = true; } { is = nest.ssh; nixos.services.openssh.enable = true; }];The web node now has is = [host, web, server, nginx, ssh] after expansion. The nginx and ssh rules fire automatically — you never listed them on the node.
Using select in rules
Section titled “Using select in rules”Access other nodes from within a rule function:
nest.rules = [ { is = nest.host; nixos = { select, host, ... }: { networking.hostName = host.name; }; }];The host argument is the matched node. select gives access to siblings, children, ancestors, and filtered queries.
Next steps
Section titled “Next steps”- Multi-Environment Fleet — load balancer, multiple web servers, haproxy backend discovery
- Dynamic User Assignment — user registry, synth children, env-based policies
- Selectors reference — all selector forms