Experimental package management with Nix and NixOS

Brand New Package

© Photo by Jess Bailey on Unsplash

© Photo by Jess Bailey on Unsplash

Article from Issue 248/2021

NixOS and the Nix package manager offer a promising new approach to the challenge of managing packages in Linux.

In most Linux distributions, the files associated with the OS end up in specific places. Most Linux distributions subscribe to the filesystem hierarchy defined in the Linux Standards Base (LSB), which specifies the familiar directory names you are accustomed to if you work in Linux (/etc, /dev, /bin, etc.). On most Linux systems, if you do not have the files in the right places, the applications will not find them. But experimentation is at the heart of Linux, and every rule has an exception. An innovative project called NixOS [1] takes a different approach to system configuration and package management.

On NixOS, all files are in the Nix store. For applications to find them, NixOS links to the correct locations with symlinks. This approach makes all kinds of things possible. For instance, you can have several versions of any library and let the application know which link to use. For development environments, you can even test an application using system files from different distributions, just using the package manager.

On a NixOS system, everything is reproducible. A good backup of your home directory and a few *.nix files is all you need to get back up after a crash.

At the heart of NixOS is the Nix package manager. Nix is a cross-platform package manager that can run on other distros as well, but NixOS was created to provide a native environment for testing and experimenting with Nix.

When you make a change to your system, NixOS creates a new generation. A generation contains all the links to the software you want to run. When you come into your favorite boot manager (GRUB?), it will give you the default boot or alternatives. The alternatives contain all versions of the system you have created since you installed. Yes, as you will learn later in this article, saving all previous versions of the system can waste a lot of disk space, so you will want to take the time to retire older generations you are no longer using.

Advantages and Disadvantages

From a practical point of view, changing your configuration is easier on NixOS than on other distributions. Let's say you want to use another window manager but still keep the first one for backup. If you make the install and something goes wrong, or if you change your mind, you can roll back. To roll back, reboot and pick the earlier generation.

You might be missing a few packages, but Nix is popular enough to boast 80 thousand packages in the default repository. You can create your own package if you are capable enough. There is also support for the AppImage and Flatpak systems, although Snap support seems a little lacking.

NixOS does not have a graphical installer. You need to change the settings for keyboard, locale desktop environment, and similar by changing the configuration.nix file. Keep in mind, also, that the Nix package manager does not have a graphical interface, which could be a disadvantage for some users.

When you first try NixOS, all you need to do is partition your drives, or label the existing ones, and run nixos-generate-config. Next, you change one file (configuration.nix), run nixos-install, and you are done.

NixOS lets you put all the packages that you want to use in the configuration.nix file. You can then use configuration.nix to recreate the same configuration on any other machine.

Nix Package Manager

The real strength of NixOS is the Nix package manager. The package manager has many unique features, such as rollback, support for multiple versions, and the ability to reproduce the install. The Nix package manager is an interesting option if you are developing software and you are getting tired of the multitude of virtual environments.

To fetch the Nix package manager only, you need to use the link available at the project website. The installer will ask you for sudo access to create the /nix directory as root.

sudo mkdir /nix
curl -L https://nixos.org/nix/install | sh

The more cautious of you will download the script and read it through before running it. Bear in mind though, that if you run the install with a non-privileged user, the script will ask for root, so it can create and write to the /nix directory.

You can also create a multi-user environment with the installer script. To do this, use the --daemon option:

sh <(curl -L https://nixos.org/nix/install) --daemon

Notice that you are still piping the script to the shell. Many seasoned administrators will not bat an eyelid over this, except for the security implications of running a script straight from a URL. You can see the start of the script in Figure 1.

Figure 1: The Nix package manager is very informative. If you pay attention, you will know every detail of your system.

The installer is aware of whether you have already installed Nix before and warns you about it.

The installer has several different configuration options, depending on what you want to do, but the main idea is to support any version of software at any time. One option is to install the Nix package manager using the installer and then pick a package and see if it has a version you like.

nix-env -i gimp

After having installed Gimp, you use the which command to discover the version:

which gimp

It is a good idea to check through the applications you are already using and see if they are present and maintained in the NixOS repositories. NixOS is still not very common, so some packages may not have the latest available version. If you want to check what software is available before installing, the NixOS website has a great searchable list (Figure 2).

Figure 2: The NixOS website includes a convenient package search feature.

After you have installed and tested a few packages, you should consider the space on your system. Due to the store and the way Nix stores the files, you may have many binary files that are identical. To fix this, search through the Nix store and re-link the files. Don't worry – there is a simple command line tool for this task. Check your Nix store using the nix-store command:

nix-store --optimise

Best practice is to have NixOS do this automatically on a regular basis. What the command does is go through all the binaries and compare them. When it finds a match, it creates a new link and erases the, now unnecessary, file. When you have tried your favorite applications, you can list them using the nix-env command again. Any applications that you cannot find in the Nix repositories might be available using AppImage and Flatpak. Support for Snap packages is a bit more dubious. To store your choices in a separate file, redirect the result to a text file:

nix-env -q >>Nix-applications.txt

You can use this list when you decide to switch your entire system to NixOS.

Dev Environments

Once you install the Nix package manager, you can use it to keep your development environments clean and consistent. With the nix-shell command, you can specify exactly what versions you have available. If anyone else is sharing the project, they can use the default.nix and shell.nix files to create an environment identical to yours.

To install an individual package, use the -p option. If you want to run Python without installing on your system, or a version other than your current system, try the following:

nix-shell -p python3

You will get a prompt (Figure 3).

Figure 3: The nix-shell command shows that the Python version is different.

Theoretically, you could install your whole environment with the -p option, but that would be counter productive. Instead, you can put all the complicated stuff in the shell.nix and default.nix files.

Inside these files, you can define your installation. The nix-shell command calls the shell.nix file first. Listing 1 shows an old example that starts an environment for running the Teensy development board, courtesy of Richard Zetterberg [2].

Listing 1

Teensy Environment

01 shell.nix:
03 { system ? builtins.currentSystem }:
05 let
06   pkgs = import <nixpkgs> { inherit system; };
07 in
08   pkgs.callPackage ./default.nix {}
11 default.nix:
13 { stdenv, lib, gcc, gcc-arm-embedded-, teensy-loader-cli }:
15 stdenv.mkDerivation rec {
17   buildInputs = [
18     gcc
19     gcc-arm-embedded-4_7
20     teensy-loader-cli
22   ];
23 }

In Listing 1, the curly brackets at the top contain the environment you need for this shell. In most cases, you will put stdenv here. You can see that this file needs gcc, lib, and the special gcc version for ARM devices. This does not tell you how to compile the package, though, which you do with stdenv.mkDerivation. In Nix parlance, the word derivation means building something from something else.

To make this work, you create the directory and place the files inside. Only one of the files is required, but most people mix in a separate default.nix to separate the parts of the system. In the file, the most important part you want to know about is the curly brackets: {...}. The curly brackets contain the standard environment you want to take from. The <nixpkgs> references the list of files that exist in the repository. For a shell to work, you only need to put those curly brackets in and then add pkgs.mkshell.

The little script file in Listing 2 gives you the ability to start Python 3.8 in a shell. Since the flask packages are also added, you also have those modules available. To find the packages you want, see the NixOS website package page [3]. When you run nix-shell, the install happens on its own. You do not need to install it first.

Listing 2

Python 3.8

01 { pkgs ? <nixpkgs> , ... }:
03 with pkgs;
04 mkshell {
05         buildInputs = [
06         python38Packages.flask
07         ];
08 }

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy Linux Magazine

Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

  • NixOS 22.5 Is Now Available

    The latest release of NixOS with a much-improved package manager and a user-friendly graphical installer.

  • NixOS 21.11 Now Available for Download

    NixOS “Porcupine” has been made available for installation and includes numerous improvements.

  • NixOS

    The innovative NixOS makes it easy to test and deploy new configurations – on the hardware and in the cloud

  • NixOS 24.05 Is Ready for Prime Time

    The latest release of NixOS (Uakari) has arrived and offers its usual reproducible, declarative, and reliable goodness.

  • Next Gen Distributions

    With systemd poised to revolutionize the init process, we look at Linux distributions that have left the familiar path, use new approaches and techniques, and are paving the way for the next generation of Linux distros.

comments powered by Disqus
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs
Subscribe to our ADMIN Newsletters

Support Our Work

Linux Magazine content is made possible with support from readers like you. Please consider contributing when you’ve found an article to be beneficial.

Learn More