A problem with the default NixOS configuration.nix generated by the official installer is that it is not “pure” and thus not reproducible (see here), as it still uses a mutable Nix channel (which is generally discouraged). For this reason (among others), it is recommended to immediately switch to using Flakes for our NixOS configuration. Doing this is pretty simple. Just add a flake.nix file in /etc/nixos:
sudo nvim /etc/nixos/flake.nixAdd the following:
# /etc/nixos/flake.nix
{
inputs = {
# NOTE: Replace "nixos-23.11" with that which is in system.stateVersion of
# configuration.nix. You can also use latter versions if you wish to
# upgrade.
nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.11";
};
outputs = inputs@{ self, nixpkgs, ... }: {
# NOTE: 'nixos' is the default hostname set by the installer
nixosConfigurations.nixos = nixpkgs.lib.nixosSystem {
# NOTE: Change this to aarch64-linux if you are on ARM
system = "x86_64-linux";
modules = [ ./configuration.nix ];
};
};
}-
Replace
nixos-23.11with the version fromsystem.stateVersionin your/etc/nixos/configuration.nix. If you wish to upgrade right away, you can also use latter versions, or usenixos-unstablefor the bleeding edge. -
x86_64-linuxshould beaarch64-linuxif you are on ARM
Now, /etc/nixos is technically a flake. We can “inspect” this flake using the nix flake show command:
$ nix flake show /etc/nixos
error: experimental Nix feature 'nix-command' is disabled; use '--extra-experimental-features nix-command' to override
Oops, what happened here? As flakes is a so-called “experimental” feature, you must manually enable it. We’ll temporarily enable it for now, and then enable it permanently latter. The --extra-experimental-features flag can be used to enable experimental features. Let’s try again:
$ nix --extra-experimental-features 'nix-command flakes' flake show /etc/nixos
warning: creating lock file '/etc/nixos/flake.lock'
error:
… while updating the lock file of flake 'path:/etc/nixos?lastModified=1702156351&narHash=sha256-km4AQoP/ha066o7tALAzk4tV0HEE%2BNyd9SD%2BkxcoJDY%3D'
error: opening file '/etc/nixos/flake.lock': Permission denied
Progress, but we hit another error—Nix understandably cannot write to root-owned directory (it tries to create the flake.lock file). One way to resolve this is to move the whole configuration to our home directory, which would also prepare the ground for storing it in Git. We will do this in the next section.
flake.lock
Nix commands automatically generate a (or update the) flake.lock file. This file contains the exacted pinned version of the inputs of the flake, which is important for reproducibility.
Move configuration to user directory
Move the entire /etc/nixos directory to your home directory and gain control of it:
$ sudo mv /etc/nixos ~/nixos-config && sudo chown -R $USER ~/nixos-configYour configuration directory should now look like:
$ ls -l ~/nixos-config/
total 12
-rw-r--r-- 1 srid root 4001 Dec 9 16:03 configuration.nix
-rw-r--r-- 1 srid root 224 Dec 9 16:12 flake.nix
-rw-r--r-- 1 srid root 1317 Dec 9 15:43 hardware-configuration.nix
Now let’s try nix flake show on it, and this time it should work:
$ cd ~/nixos-config
$ nix --extra-experimental-features 'nix-command flakes' flake show
warning: creating lock file '/home/srid/nixos-config/flake.lock'
path:/home/srid/nixos-config?lastModified=1702156518&narHash=sha256-nDtDyzk3fMfABicFuwqWitIkyUUw8BZ4SniPPyJNKjw%3D
└───nixosConfigurations
└───nixos: NixOS configuration
Voila! Incidentally, this flake has a single output, nixosConfigurations.nixos, which is the NixOS configuration itself.
Once flake-ified, we can use the same command to activate the new configuration but we must additionally pass the --flake flag, viz.:
# The '.' is the path to the flake, which is current directory.
$ sudo nixos-rebuild switch --flake .If everything went well, you should see something like this:

Excellent, now we have a flake-ified NixOS configuration that is pure and reproducible!