This thread got referenced recently, and I’m struck by two things: the variety of strategies used here, and surprise that the one I use isn’t mentioned. So I’m adding it just for posterity.
I just use git branches. There’s a branch for each host, checked out in that host’s /etc/nixos
. Each of those is a branch off main
, started at the time the host was first installed.
Ideally, the only unique things in the per-host branches are the {hardware-,}configuration.nix
files, and my install steps edited for the specifics used on that system at install time (disk names and partitioning sizes, mostly).
I keep configuration.nix
as small as possible, with only truly host-specific things. Networking, any special kernel modules and options, boot loader, and stateVersion, mostly. I could probably merge the hardware- file into the main configuration, but can’t be bothered.
Everything else comes from imports of files in a common/
subdir. The set of imports is the main declaration of what the host is / does.
I maintain the common/*.nix
files in the main
branch, and merge that into each host branch.
Sometimes, the ideals above slip a little, and I need to do a local edit on one of the branches, maybe because of a broken package blocking an upgrade, or an experiment, or because my common code turns out to be not quite general after all and I don’t know how or have time to fix it right then. That’s just normal merging until conflicts prompt me to solve it in a better way.
I did it this way when I first started with NixOS, because it seemed obvious to me as a method I knew how to do, and because I didn’t know enough nix to have confidence I wouldn’t get trapped or blocked or make a mess having to make code “smarter”.