Nix, NixOS

I'm a couple years deep into running NixOS as the Linux distribution of choice for my desktop computer and homelab, and as of last month also my laptop. I'd say I'm at a point now where I have a decent understanding of managing multiple NixOS systems, how to troubleshoot when Nix errors out, and how to figure out what Nix things I need to do whatever thing I'm trying to do.

So on this page you'll find all about how I use Nix and NixOS, I hope it's useful to you.

A good base

I always use the base configuration that nixos-generate-config provides during the initial setup and installation of NixOS. It provides a minimal configuration with comments scattered throughout, that after I've gone through it and adjusted as necessary, leaves me with a running system that I can now iterate on.

It's not uncommon for me to get to 50+ generations built before landing on a configuration I'm ready to start using properly.

For example, the laptop I'm writing this on right now is at generation 53 and I've only installed NixOS on it about a month ago.

$ sudo nix-env --profile /nix/var/nix/profiles/system --list-generations

52   2026-06-11 16:07:19
53   2026-06-24 14:33:39   (current)

Useful documentation → Nix Cookbook

The ones to definitely have set from the start are networking.hostName = "cool-system"; for your machine's name, console.keyMap = "your-keyboard-layout"; if you're not using a QWERTY-based keyboard layout and services.openssh.enable = true; when you're setting up a server (and don't forget to add your public key to users.users.<name>.openssh.authorizedKeys.keys of your user).

Version control

As soon as I have a system running NixOS I'll set up git to start tracking changes. I like to make my $USER the owner of /etc/nixos, turn it into a git repository, commit what exists so far and then push to a remote.

sudo chown -R $USER:users /etc/nixos
cd /etc/nixos
git init
git add .
git commit -m 'Initial NixOS configuration commit.'
git remote add <remote>
git push -u <remote> <branch>

Then any time changes are made I'll stage them to be committed, do a nixos-rebuild and if all is well, commit and push.

cd /etc/nixos
# Make changes ...
git add .
sudo nixos-rebuild switch # or: sudo nixos-rebuild boot
git commit -m '<describe what changed>'
git push

There are many other ways to version control a NixOS configuration and deploy it, but I like this approach because it's dead simple.

Organizing

Eventually doing everything in configuration.nix will become cumbersome, which is when I'll start to take the larger sections and split them out into their respective files. Usually the one I'll start with is services as that tends to be the majority of my configurations.

/etc/nixos/
├── configuration.nix
└── services/
    ├── default.nix
    ├── openssh.nix
    └── ...

Then in my configuration.nix I'll add the services directory to the imports and in the services/default.nix I'll add each individual service file as an import as well.

# in configuration.nix:
imports = [
  ./services
];
# services/default.nix:
{ ... }:

{
  imports = [
    ./openssh.nix
    # additional services ...
  ];
}
# example services/openssh.nix:
{ config, lib, pkgs, ... }:

{
  services.openssh = {
    enable = true;
    settings = {
      PasswordAuthentication = "no";
      PermitRootLogin = "no";
    };
  };
}

Repeat for the other services and configuration.

I don't separate everything out like this, some configuration I'll only make a separate .nix file for or it can stay in configuration.nix, but if a part of the configuration gets too big it'll be evicted to another place.

More to come

When I get around to it. :)