Declarative System Management with NixOS: Using nixos-rebuild for Reliable Updates
Imperative system changes cause drift that makes replication hard. NixOS solves this by defining the entire system in a single declarative file.
08 Dec 2025, 18:38 UTC

The Problem of Imperative System Drift
Most Linux distributions rely on imperative commands to install packages and edit configuration files. Over time the exact sequence of steps is forgotten, leading to "system drift" that makes it difficult to reproduce a working environment on another machine or after a disk failure.
How nixos-rebuild Creates a New Generation
NixOS treats the whole operating system as a single functional value defined in a file, usually /etc/nixos/configuration.nix. When you run sudo nixos-rebuild switch, Nix evaluates the expression, builds or downloads the required derivations into the /nix/store, and then activates a new system generation. A generation is an immutable snapshot of the entire system state; the bootloader is updated to point to this new generation, and the change is atomic—either the whole system switches or nothing changes.
Worked Example: Adding a Web Server and Tools
Below is a minimal declarative configuration that installs Vim, Git, and Curl, enables Nginx with a custom worker setting, and creates a user named devuser in the wheel group.
{ boot.loader.system = "systemd-boot";
environment.systemPackages = with pkgs; [ vim git curl ];
services.nginx = {
enable = true;
settings = { worker_connections = "1024"; };
};
users.users.devuser = {
isUser = true;
groups = [ "wheel" ];
password = "";
};
}
To apply this configuration, execute the following command with root privileges:
sudo nixos-rebuild switch
After the command finishes, you can verify the new generation exists:
nix-env --list-generations
The output will show a higher generation number, confirming that a new snapshot has been created and activated.
Trade‑offs and Limitations
- Disk consumption: Each generation remains in the
/nix/storeuntil explicitly removed, which can lead to rapid disk growth. Regular cleanup withnix-collect-garbage -dis recommended. - Learning curve: The Nix expression language is functional and lazy, differing significantly from Bash or YAML, which can increase initial onboarding time.
- Imperative changes are lost: Any manual edits made directly to files in
/etcor manual package installs (e.g.,sudo apt install) will be overwritten or ignored on the nextnixos-rebuildbecause they are not captured in the declarative configuration.
Actionable Steps to Adopt Declarative Management
- Begin by moving your most critical, repeatable settings into
configuration.nix—for example, system packages and essential services. - Test changes in a non‑production environment using
sudo nixos-rebuild testbefore switching. - List generations regularly with
nix-env --list-generationsto monitor growth. - Schedule periodic garbage collection, e.g., a weekly cron job running
nix-collect-garbage --delete-older-than 30d. - If a rebuild leaves the system unbootable, reboot and select a previous generation from the GRUB or systemd‑boot menu, then run
sudo nixos-rebuild switch --rollbackto make it current again.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.