NixOS is a GNU/Linux distribution that aims to improve the state of the art in system configuration management. In existing distributions, actions such as upgrades are dangerous: upgrading a package can cause other packages to break, upgrading an entire system is much less reliable than reinstalling from scratch, you can’t safely test what the results of a configuration change will be, you cannot easily undo changes to the system, and so on. We want to change that. NixOS has many innovative features:

Declarative system configuration model

In NixOS, the entire operating system — the kernel, applications, system packages, configuration files, and so on — is built by the Nix package manager from a description in a purely functional build language. The fact that it’s purely functional essentially means that building a new configuration cannot overwrite previous configurations. Most of the other features follow from this.

You configure a NixOS system by writing a specification of the functionality that you want on your machine in /etc/nixos/configuration.nix. For instance, here is a minimal configuration of a machine running an SSH daemon:

{
  boot.loader.grub.device = "/dev/sda";

  fileSystems."/".device = "/dev/sda1";

  services.sshd.enable = true;
}

After changing /etc/nixos/configuration.nix, you realise the configuration by running this command:

$ nixos-rebuild switch

This command does everything necessary to make the configuration happen, including downloading and compiling OpenSSH, generating the configuration files for the SSH server, and so on.

Reliable upgrades

Another advantage of purely functional package management is that nixos-rebuild switch will always produce the same result, regardless of what packages or configuration files you already had on your system. Thus, upgrading a system is as reliable as reinstalling from scratch.

Atomic upgrades

NixOS has a transactional approach to configuration management: configuration changes such as upgrades are atomic. This means that if the upgrade to a new configuration is interrupted — say, the power fails half-way through — the system will still be in a consistent state: it will either boot in the old or the new configuration. In most other systems, you’ll end up in an inconsistent state, and your machine may not even boot anymore.

Rollbacks

Because the files of a new configuration don’t overwrite old ones, you can (atomically) roll back to a previous configuration. For instance, if after a nixos-rebuild switch you discover that you don’t like the new configuration, you can just go back:

$ nixos-rebuild switch --rollback
Grub boot menu

In fact, all old system configurations automatically show up in the Grub boot menu. So if the new configuration crashes or doesn’t boot properly, you can just roll back by selecting an older configuration in the Grub boot menu. Rollbacks are very fast: it doesn’t involve lots of files having to be restored from copies.

Reproducible system configurations

NixOS’ declarative configuration model makes it easy to reproduce a system configuration on another machine (for instance, to test a change in a test environment before doing it on the production server). You just copy the configuration.nix file to the target NixOS machine and run nixos-rebuild switch. This will give you the same configuration (kernel, applications, system services, and so on) except for ‘mutable state’ (such as the stuff that lives in /var).

Safe to test changes

NixOS makes it safe to test potentially dangerous changes to the system, because you can always roll back. (Unless you screw up the boot loader, that is…) For instance, whether the change is as simple as enabling a system service, or as large as rebuilding the entire system with a new version of Glibc, you can test it by doing:

$ nixos-rebuild test

This builds and activates the new configuration, but doesn’t make it the boot default. Thus, rebooting the system will take you back to the previous, known-good configuration.

An even nicer way to test changes is the following:

$ nixos-rebuild build-vm
$ ./result/bin/run-*-vm

This builds and starts a virtual machine that contains the new system configuration (i.e. a clone of the configuration of the host machine, with any changes that you made to configuration.nix). The VM doesn’t share any data with the host, so you can safely experiment inside the VM. The build-vm command is very efficient (it doesn’t require a disk image for the VM to be created), so it’s a very effective way to test changes.

Source-based model, with binaries

The Nix build language used by NixOS specifies how to build packages from source. This makes it easy to adapt the system — just edit any of the ‘Nix expressions’ for NixOS or Nixpkgs in /etc/nixos, and run nixos-rebuild. However, building from source is also slow. Therefore Nix automatically downloads pre-built binaries from nixos.org if they are available. This gives the flexibility of a source-based package management model with the efficiency of a binary model.

Consistency

The Nix package manager ensures that the running system is ‘consistent’ with the logical specification of the system, meaning that it will rebuild all packages that need to be rebuilt. For instance, if you change the kernel, Nix will ensure that external kernel modules such as the NVIDIA driver will be rebuilt as well — so you never run into an X server that mysteriously fails to start after a kernel security upgrade. And if you update the OpenSSL library, Nix ensures that all packages in the system use the new version, even packages that statically link against OpenSSL.

Multi-user package management

On NixOS, you do not need to be root to install software. In addition to the system-wide ‘profile’ (set of installed packages), all user have their own profile in which they can install packages. Nix allows multiple versions of a package to coexist, so different users can have different versions of the same package installed in their respective profiles. If two users install the same version of a package, only one copy will be built or downloaded, and Nix’s security model ensures that this is secure. Users cannot install setuid binaries.

How does NixOS work?

NixOS is based on Nix, a purely functional package management system. Nix stores all packages in isolation from each other under paths such as

/nix/store/5rnfzla9kcx4mj5zdc7nlnv8na1najvg-firefox-3.5.4/

The string 5rnf... is a cryptographic hash of all input used to build the package. Packages are never overwritten after they have been built; instead, if you change the build description of a package (its ‘Nix expression’), it’s rebuilt and installed in a different path in /nix/store so it doesn’t interfere with the old version. NixOS extends this by using Nix not only to build packages, but also things like configuration files. For instance, the configuration of the SSH daemon is also built from a Nix expression and stored under a path like

/nix/store/s2sjbl85xnrc18rl4fhn56irkxqxyk4p-sshd_config

By building entire system configurations from a Nix expression, NixOS ensures that such configurations don’t overwrite each other, can be rolled back, and so on.

A big implication of the way that Nix/NixOS stores packages is that there is no /bin, /sbin, /lib, /usr, and so on. Instead all packages are kept in /nix/store. (The only exception is a symlink /bin/sh to Bash in the Nix store.) Not using ‘global’ directories such as /bin is what allows multiple versions of a package to coexist. Nix does have a /etc to keep system-wide configuration files, but most files in that directory are symlinks to generated files in /nix/store.

Status

NixOS is available for download. Since NixOS is a relatively young Linux distribution, you may find that certain things that you need are missing (e.g., certain packages or support for specific hardware), so you may need to add those yourself. Here are some highlights of what NixOS currently provides:

License

NixOS is free software, released under a permissive MIT/X11 license.