Adding a Host

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.