Adding a Host
Table of Contents
Adding a machine to an emanix fleet is four edits and a build. The build is the point: it either evaluates or it does not, and you find out before touching the machine.
1. 1. Declare the host
In flake.nix, add an entry to nixosConfigurations:
<host> = mkHost {
hostName = "<host>";
username = "<you>";
role = "workstation"; # a LABEL — it selects nothing
hardware = ./hardware/<machine>.nix;
extraModules = [
./hosts/<host>/configuration.nix
disko.nixosModules.disko
./hardware/disko/<host>.nix
emanix.nixosModules.ewm # only if you want the compositor
];
homeModules = [ ./home/<you>.nix ];
};
A WSL host takes no hardware argument — the WSL module supplies boot and
mounts.
Note what is not implied by role. It imports nothing. If this host should
run the compositor, you import nixosModules.ewm yourself, as above; if it
needs audio, printing or containers, those are your modules too. The
distribution ships one shape, and you compose the rest — see
Architecture.
2. 2. Write the hardware module
Only genuine device facts: initrd modules, firmware, power management. Keep audio, Bluetooth, touchpad and the bootloader out of it — those are not device identity, they are choices about how you want the machine to behave, and they belong in your own modules alongside everything else about this host.
If the machine has a GPU the compositor depends on, load it in the initrd. Bringing it up after userspace starts loses the display-master race against a compositor launched from a TTY.
3. 3. Describe the disk
Disk layout is declarative. Write a disko module describing the partition
table, encryption and filesystems.
Do not also hand-write fileSystems or the LUKS devices in the hardware
module. Disko generates them; a second definition collides and the whole
configuration fails to evaluate. That failure is the guardrail working.
4. 4. Create the host anchor
hosts/<host>/configuration.nix holds what is unique to this machine — and
system.stateVersion.
Set stateVersion to the release you are installing now, and never touch it
again. It must not be shared between hosts and must not be bumped on an
existing one. It is not a version to keep current: it is a historical fact
about the install, and changing it silently changes migration behaviour.
5. 5. Verify before you touch the machine
nix flake check nix build .#nixosConfigurations.<host>.config.system.build.toplevel
Neither needs root, and neither needs the target machine.
Do not build another host's closure on an unrelated machine unless you know its inputs are cached. Source-compiling a desktop's package set on a small virtualised host can exhaust its memory and take the whole environment down. When all you need is a no-op proof, compare derivation paths instead — this is cheap, pure evaluation, and it answers "did my refactor change anything?" exactly:
nix eval --raw .#nixosConfigurations.<host>.config.system.build.toplevel.drvPath
Identical paths before and after mean the change is provably inert. Differing paths tell you to go find out why — and the answer is sometimes legitimate, like an error message that now names a renamed option.
6. 6. Install and join
Follow Installation. emanix-firstboot runs
whatever you put in emanix.firstboot.text — typically joining a network,
pairing file sync, cloning your flake and confirming secrets decrypt. The
distribution supplies the convention and the build-time shellcheck; the steps
are yours.
7. Adapting emanix rather than adopting it
This split used to need a warning. It no longer does, because the split is now
the repository boundary: everything general is in Emanix, and everything
personal is in the flake that consumes it. The ioshi/ module layout, the
theme system, the compositor and the host composer work for anyone. The shell
aliases, the agent, the git identity and the network enrolment are not in here
to inherit.
The honest summary is that Emanix is public-shaped rather than a product. It was written with an outside reader in mind, which is why the seams are documented and why the personal half was moved out — but it is still one person's machine, and the interesting thing to take from it is the boundary, not the package list.