Magic Deployments with nixos-rebuild
One of the things you learn after installing NixOS for the first time is that
all these tasks are basically the same from a tooling perspective:
Adding/removing a package, massively changing the system configuration, or
simply updating it.
After changing the configuration and/or the inputs, you run
and the system is deployed.
If the configuration turns out to be bad - it can simply be rolled back!
But how does this tool work and what other cool features does it have?
The Nix & NixOS 101 class teaches how to install NixOS
and how to experiment with NixOS configurations using
As this class is already packed with so many other useful things like how to
write NixOS modules and NixOS integration tests, we are only scratching the
surface of what
nixos-rebuild can do!
nixos-rebuild is the standard tool for altering the system configuration of
an installed NixOS system.
The typical steps are, as
described in the NixOS documentation:
- Change NixOS configuration
- by changing the configuration in your
- by updating the inputs with
nix flake update
- by changing the configuration in your
sudo nixos-rebuild switch
That’s it. You might want to reboot the system if the kernel was updated.
How Does It Look Like?
Let’s perform a full system upgrade:
$ nix flake update --commit-lock-file warning: updating lock file '/home/tfc/src/nixos-configs/flake.lock': • Updated input 'nixpkgs': 'github:NixOS/nixpkgs/ac1acba43b2f9db073943ff5ed883ce7e8a40a2c' (2023-07-23) → 'github:NixOS/nixpkgs/f3fbbc36b4e179a5985b9ab12624e9dfe7989341' (2023-07-26) warning: committed new revision 'ba119606b5ca47f43b8fa338bd02fe37aa6d405f'
--commit-lock-fileargument is optional but handy if the configuration is stored in a
gitrepository. If you are going to commit the lock file anyway,
nix flake updatecan commit it for you.
After an update, the system typically needs to be rebuilt even without other configuration changes:
$ sudo nixos-rebuild switch building the system configuration... stopping the following units: accounts-daemon.service, cpufreq.service, systemd-udevd-control.socket, systemd-udevd-kernel.socket, systemd-udevd.service NOT restarting the following changed units: display-manager.service, libvirt-guests.service, systemd-fsck@dev-disk-by\x2duuid-091D\x2d4B27.service activating the configuration... warning: not applying GID change of group ‘localtimed’ (990 -> 325) in /etc/group warning: not applying UID change of user ‘localtimed’ (993 -> 325) in /etc/passwd setting up /etc... reloading user units for tfc... setting up tmpfiles reloading the following units: dbus.service restarting the following units: home-manager-tfc.service, nix-daemon.service, polkit.service, sshd.service starting the following units: accounts-daemon.service, cpufreq.service, systemd-udevd-control.socket, systemd-udevd-kernel.socket the following new units were started: libvirtd.service
If the new configuration is not good for some reason, it can be rolled back:
$ sudo nixos-rebuild switch --rollback [sudo] password for tfc: switching profile from version 359 to 358 stopping the following units: accounts-daemon.service, cpufreq.service, systemd-udevd-control.socket, systemd-udevd-kernel.socket, systemd-udevd.service NOT restarting the following changed units: display-manager.service, libvirt-guests.service, systemd-fsck@dev-disk-by\x2duuid-091D\x2d4B27.service activating the configuration... warning: not applying GID change of group ‘localtimed’ (990 -> 325) in /etc/group warning: not applying UID change of user ‘localtimed’ (993 -> 325) in /etc/passwd setting up /etc... reloading user units for tfc... setting up tmpfiles reloading the following units: dbus.service restarting the following units: home-manager-tfc.service, nix-daemon.service, polkit.service, sshd.service starting the following units: accounts-daemon.service, cpufreq.service, systemd-udevd-control.socket, systemd-udevd-kernel.socket the following new units were started: libvirtd.service
The activation of a new/old configuration takes only seconds depending on how many services need to be restarted.
What Other Features Does
nixos-rebuild provides functionality on two different axes:
- Command Targets
- Just evaluate the NixOS configuration
- Evaluate & build
- Evaluate, build, and activate the new NixOS config temporarily or permanently
- Dry-run activation to see the impact on the system
- Build and run a VM for testing
- Local NixOS rebuilds
- Remote deployment to other hosts
- Remote building of the new NixOS configuration
The remote building capabilities of
nixos-rebuild are very interesting, too.
We will have a look at them in
the next blog article.
So what are the command targets? These are the most interesting ones for day-to-day use:
||Builds and activates the system configuration with immediate effect. In addition to that, it installs the configuration in the bootloader.|
||Builds the config and updates the bootloader list without activating the system immediately.|
||Only evaluates the config without building it.|
||Builds the config and print which changes would be performed on the current system during activation.|
||Builds the config and generates a script that starts this configuration as a VM on your local system.|
build-vm part is interesting - let’s try it out:
$ nixos-rebuild build-vm building the system configuration... Done. The virtual machine can be started by running /nix/store/yscmmshi2q0dmr6xcfdnhz3829sd5lqz-nixos-vm/bin/run-jongepad-vm $ ./result/bin/run-jongepad-vm Disk image do not exist, creating the virtualisation disk image... Formatting '/home/tfc/src/nixos-configs/jongepad.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1073741824 lazy_refcounts=off refcount_bits=16 Virtualisation disk image created.
Running the script starts the VM and after boot, it shows the same login manager as my laptop does:
Of course, we can’t really log in without setting a password first, because the user passwords are not part of the NixOS configuration. During the installation of a local NixOS system, we set them imperatively. Remote system deploys typically use SSH key authorization instead of passwords.
Other Interesting Parameters
With every activation, the path
/nix/var/nix/profiles/system is set to the new
For every activated configuration, nix adds another symlink
/nix/var/nix/profiles/system-XYZ-link to the profiles folder, where
the number of the current system.
Each of these systems is considered another NixOS system generation.
--rollback is used in combination with
nixos-rebuild does not build and activate a new system version but reactivate
the last one.
--flake path/to/flake/repo#systemName to the command line tells
nixos-rebuild to use the flake at path
path/to/flake/repo and use the
system configuration with the name
#systemName part is omitted,
nixos-rebuild tries to deduce it from
the local hostname.
--flake parameter can be omitted if the system has a
/etc/nixos/flake.nix flake file.
The system name is also automatically deduced from the host name in this case.
To make sure that the latest version of
nix is used for the deployment,
nixos-rebuild obtains the latest
Using this flag can accelerate the process by trusting that the currently
installed version is compatible.
MacOS Users also need to use this flag when remote-deploying to a NixOS system from their Mac.
It is possible to create system configurations with specific profile names, like for example “maintenance”, or “lanparty”. These are installed into the bootloader next to the default system profile and can be selectively booted when needed.
Summary & Outlook
Installing, removing, upgrading, and configuring packages and system services is painless on NixOS: Instead of tampering with the system state by imperatively installing packages and manipulating service configurations, we have a central NixOS configuration that can be versioned and describes it all.
Given any NixOS configuration, we can
switch to this configuration
with a single command using
If the new config turns out to be bad, we can simply
--rollback any time, or
boot into the last system generation!
Even before doing that, we can
build-vm to test if our
config makes sense even before deploying it to a real system.
The next article shows how to use
nixos-rebuild to remotely deploy NixOS
on target machines via network.
In addition to that, we will see how to remote build configurations on other
hosts via network, may that be for performance reasons or cross-compilation.