Adding a Host
This page describes how to add a new machine to the flake. Everything below is
checked against the code in lib/flake-utils.nix — if a function is named here,
it exists.
Previous versions of this page documented
mkWorkstation,mkServer,mkGaming,mkLaptop,mkVM,mkContainer,mkDevelopment,mkMinimal,mkMediaServer,mkDesktopHostandmkServerHost. None of those functions ever existed in this repository — they were removed as an anti-pattern (see NIXOS-ANTI-PATTERNS.md) but the documentation was never updated. There is one builder,mkSystem, and it takes the machine type as a parameter.
The short version
# 1. Copy the closest starting point
cp -r hosts/desktop-template hosts/my-desktop
# 2. Generate hardware configuration for THIS machine
sudo nixos-generate-config --show-hardware-config \
> hosts/my-desktop/hardware-configuration.nix
# 3. Register it: uncomment a line in the "ADD YOUR OWN HOSTS HERE" block
# near the bottom of flake.nix
# 4. Build it
sudo nixos-rebuild switch --flake .#my-desktop
Step 3 in full — in flake.nix:
nixosConfigurations = flakeUtils.allConfigurations // {
my-desktop = flakeUtils.mkSystem {
hostname = "my-desktop";
profile = "workstation";
};
};
Starting points in hosts/: desktop-template, laptop-template,
server-template, wsl2-template.
mkSystem
The single builder for NixOS hosts. Defined in lib/flake-utils.nix.
flakeUtils.mkSystem {
hostname = "my-server"; # required
system = "aarch64-linux"; # optional, default "x86_64-linux"
profile = "server"; # optional, default "workstation"
extraModules = [ ./extra.nix ];# optional, default [ ]
}
| Parameter | Type | Default | Meaning |
|---|---|---|---|
hostname |
string | (required) | Must match the directory name under hosts/. mkSystem imports hosts/<hostname>/configuration.nix. |
system |
string | "x86_64-linux" |
Nix system double. |
profile |
enum | "workstation" |
One of workstation, server, laptop, gaming, development, minimal. |
extraModules |
list of modules | [ ] |
Appended to the module list. |
What profile actually does
profile is metadata, not a package set. It is passed through flakeMeta
to modules/core/system-identification.nix, where it drives the system
description, system.nixos.tags, the NIXOS_PROFILE environment variable and
the nixos-info command.
It does not by itself install packages or enable services. What your host
gets comes from the modules its configuration.nix imports. Setting
profile = "server" on a host whose configuration.nix imports the desktop
modules still gives you a desktop.
What every host gets automatically
mkSystem always adds:
hosts/<hostname>/configuration.nix- the Home Manager NixOS module (with
useGlobalPkgsanduseUserPackages) - the agenix NixOS module, for secrets
- a
flakeMetamodule providing/etc/nixos/flake-metadata.json, theNIXOS_*environment variables and thenixos-infocommand
homeProfiles is passed via specialArgs, so a host’s home.nix can refer to
the shared Home Manager profiles without relative paths.
Other builders
These exist and are used by this repository, but you are unlikely to need them for an ordinary machine.
| Function | Purpose |
|---|---|
mkSystem |
Normal NixOS host. This is the one you want. |
mkWSLSystem |
NixOS under WSL2; adds the NixOS-WSL module. |
mkInstaller |
Installer ISO from hosts/installer-isos/. |
mkMacOSInstaller |
Installer ISO from hosts/macos-isos/. |
The pre-built sets templates, testConfigs, installers, macosVMs and
wslConfigs are merged into allConfigurations, which is what flake.nix
exposes as nixosConfigurations.
Examples
Headless server on ARM
my-server = flakeUtils.mkSystem {
hostname = "my-server";
system = "aarch64-linux";
profile = "server";
};
Laptop with extra host-specific modules
my-laptop = flakeUtils.mkSystem {
hostname = "my-laptop";
profile = "laptop";
extraModules = [
./hosts/my-laptop/thinkpad-tweaks.nix
];
};
Overriding a setting without a separate file
extraModules takes inline modules too:
my-desktop = flakeUtils.mkSystem {
hostname = "my-desktop";
profile = "workstation";
extraModules = [
{ time.timeZone = "Europe/Oslo"; }
];
};
Standalone Home Manager
homeConfigurations entries are built by mkHome in flake.nix and are for
using Home Manager without NixOS:
"user@my-desktop" = mkHome { hostname = "my-desktop"; };
On a NixOS host you do not need this — mkSystem already wires Home Manager in.
Verifying before you switch
nix flake check # evaluate every host
nix build .#nixosConfigurations.my-desktop.config.system.build.toplevel --dry-run
sudo nixos-rebuild test --flake .#my-desktop # activate without a boot entry
sudo nixos-rebuild switch --flake .#my-desktop
A caveat worth knowing
hosts/*/configuration.nix in this repository imports ../../modules, which
imports every module directory including modules/profiles/, and
modules/profiles/default.nix imports workstation.nix unconditionally.
workstation.nix is not guarded by an enable option, so its desktop package set
applies to any host that imports ../../modules — including server-template.
If you are building a genuinely minimal server, import the specific module
directories you want instead of ../../modules. hosts/wsl2-template/configuration.nix
shows that selective-import style.