/etc/nixos/roles/foo/default.nix has config for the 'foo' role (eg, I have a desktop role that enables all my GUI options)
configuration.nix and hardware-configuration.nix in /etc/nixos/ are symlinked to the actual files in /etc/nixos/hosts/<hostname>/
in the imports section of each machine's configuration.nix, I import /etc/nixos/roles/foo for each role the machine should use. for your graphics card example, I have 'nvidia' and 'nvidia470' roles that pull in their respective nvidia driver (due to an old gaming laptop that requires the legacy driver version)
I have a 'core' role that all machines import, with the global config I want on every host
this allows me to version-control my entire /etc/nixos directory (managed as a private git repo, replicated using syncthing rather than pushed to Github/Gitlab/etc). the symlinks in /etc/nixos are in .gitignore because they're machine-specific, and the actual per-host config files are able to be tracked in their own directories.
I also wipe my entire rootfs every boot with a zfs snapshot rollback[2] using the impermanence module[3] to keep specific stateful data one one of two datasets with regular snapshots: one is backed up with zfs send, the other is just for cache between reboots.
It took a little puzzling to get started, because I didn’t know about the impermanence module at first, so I built my own hacky solution. But I really love this setup. And the way I don’t have cruft to clean.
Also my backups are so much smaller now :’-)
Nix flakes lets you define as many configurations as you want, and (if you don't specify one) will select based on the hostname.
It's arguably the killer feature of NixOS, if stability and purity means nothing to you.
A few weeks ago I bought a little SBC (Quartz64) for my homemade NAS project. Since I'm already a NixOS user, the bootstrap process was easy:
- Build ARM image for NixOS and boot off the device
- Clone my dotfiles and symlink my config folder into /etc/nixos
- Rebuild my system
And boom. Everything is there, my shell and coreutils and things I've come to expect all get rolled into the system. Updating it just means git pull and a system rebuild. As you say - it's not for the impatient. You have to maintain your config pretty regularly, and covering multiple devices across multiple architectures requires some deliberate config organization.
I'm not sure where I fall on the patience spectrum, but NixOS worked out pretty great for me. It's on my desktop, laptop and homeserver, and I haven't had a single bad update in my 8 months of daily driving it.