A second look at NixOS

January 1, 2022

NixOS

I had tried out NixOS around 4 to 5 years ago to see if I can use it in one of my machines, but unfortunately there was a known driver issue at that time. I have been trying it on VMs on and off in the last couple of years and the experience has been okay, but I didn’t feel comfortable enough to use it for my day to day work.

About a year ago I started using plain nixpkgs in my Ubuntu distribution to manage the software installation. Most of the packages worked fine, except some packages like xscreensaver, alacritty etc. This helped me understand nixpkgs better. I became comfortable doing package overrides, managing my xmonad configuration via nixpkgs etc.

Recently, my laptop got a motherboard upgrade and I decided to install the latest Ubuntu LTS version. While everything seemed to be fine, some of the dev dependencies caused issues. I was eventually able to fix it, but then decided that this is probably a good time for me to try out NixOS since it won’t be having these kind of issues. This post is my review of NixOS after using it for almost a year.

My requirements

My requirements from an operating system would be:

At a high level, it looked like NixOS might satisfy all these requirements.

Ease of Use

In my opinion, knowing Nix language and how nixpkgs is structured are pre-requisites to use NixOS comfortably. Fortunately my previous experience with functional languages helped me.

So I wouldn’t recommend NixOS to non-programmers. Although, I believe a project like nix-gui might simplify things in future.

Installation experience

I went through the NixOS manual and downloaded the minimal ISO image. For Ubuntu distribution, I usually install using bootable USB drives created through unetbootin. There was a note in this wiki saying Unetbootin wasn’t supported for NixOS. But I went ahead and gave it a shot. The process seemed to be successful, but the installation failed with no useful error message. I then did a fresh format of the USB and used the dd utility to write the image. The installation process worked fine after that.

Another thing which was surprising to me was that secure boot is not yet possible via NixOS. I had to go and disable it in my BIOS. That seems to be a known upstream issue.

Overall, I believe the installation experience was fine. I guess if I had used a Graphical ISO image instead of the minimal one, it would have been easier.

Development experience

Rust

I installed rustup globally and was able to easily do development without any issues. For the packages which needed system libraries, I could easily figure out the dependencies. For the cnx package, I had to create a shell.nix like this:

with import <nixpkgs> { };
stdenv.mkDerivation {
  name = "cnx";
  buildInputs = [
    pkg-config
    alsaLib
    gobject-introspection
    cairo
    glib
    pango
    xorg.libxcb
    python3Full
    openssl
    wirelesstools
    libllvm
    clang
    libclang
    rust-bindgen
    llvmPackages.libclang
    xorg.libxcb
    xorg.xcbutilwm
  ];

  shellHook = ''
    export LIBCLANG_PATH="${llvmPackages.libclang.lib}/lib";
  '';
}

Haskell

Compared to Rust, with Haskell it was slightly more challenging. There were two options:

I wanted to use the Stack build tool since I was already familiar with it and had a good experience using it. Since Stack doesn’t manage GHC in NixOS, this proved challenging to me as the compiler version I wanted wasn’t in the current nixpkgs package set.

Since rustup worked well, I installed ghcup and tried installing the compiler through it. Unfortunately that didn’t work. It downloaded a Fedora based GHC for NixOS and failed during the installation. But after looking around a bit, I was able to find the Nix package versions search page which can be used to find old versions of different packages in nixpkgs revisions easily. And that solved my problem of finding an older GHC version. Also, Cheng Shao at Zurihac made this repository which list downs all the old GHC versions from old nixpkgs revisions.

After the above problem was solved, I was able to use Stack build tool for development work seamlessly.

Other softwares

Most of the other softwares seemed to work. I didn’t face any issue with either docker, keepassxc or gnucash. But I faced an issue with mysql-workbench. It initially greeted me with an unsupported OS dialog:

Mysql-workbench on NixOS

And when I tried to connect a database, it errored out saying org.freedesktop.secrets was not provided. I wasn’t able to provide it with the database credentials properly. I tried to switch to dbeaver instead and fortunately it worked for me.

Also, one of the packages I was using for Emacs (dumb-jump) didn’t work. But I was able to easily create an upstream fix for it. This was easy for me because other nix users had faced similar issues for other Emacs packages. I wanted to try running the test suite for the package locally based on these instructions:

cd <path_to_dumb_jump>
cask
make test

I have to execute cask and then do make test. I used nix-shell to get cask executable available in the $PATH:

nix-shell -p cask
cask
bash: /nix/store/bva3nw2nvcxlrqn24f90mnm2hb60hqxw-cask-0.8.7/bin/cask:
/bin/bash: bad interpreter: No such file or directory

The above error indicates that cask has some hard-coded paths and it won’t play nicely in NixOS without some fixes. So I thought I would try fixing this later and just used the upstream CI service to run the test suite instead.

One final issue which I found annoying was whenever I tried to run any program which didn’t exist in $PATH, I saw an error message like this:

invalid_program
DBI connect('dbname=/nix/var/nix/profiles/per-user/root/channels/nixos/programs.sqlite','',...)
failed: unable to open database file at /run/current-system/sw/bin/command-not-found line 13.
cannot open database `/nix/var/nix/profiles/per-user/root/channels/nixos/programs.sqlite'
at /run/current-system/sw/bin/command-not-found line 13.

I solved it using this discourse answer, but I hope that this will be fixed soon.

Upgrade

After I had used NixOS for a few months, a new version was available. Upgrading to it was quite simple:

❯ sudo nix-channel --add https://nixos.org/channels/nixos-21.11 nixos
❯ sudo nixos-rebuild switch --upgrade

After around 15 to 20 minutes, I had the newer version running:

Before:

❯ nixos-version
21.05.4116.46251a79f75 (Okapi)

After:

❯ nixos-version
21.11.334247.573095944e7 (Porcupine)

I found it nice that I have the ability to boot back into my previous NixOS version in case something went wrong.

Community

The community around NixOS seems to be quite active and the github model makes it easy to contribute fixes. I was able to easily package various softwares which I use and didn’t find in nixpkgs:

I also contributed to nixos-hardware for the machines which I’m using:

Both of the above patches enabled running thermald by default for the machines.

I also found the Zurihac 2021 voice channel discussions quite helpful. I would like to thank everyone who answered my questions and also a special shout out to Dennis.

Recommendation

If you are planning to switch to NixOS, my recommendation would be:

NixOS has a come a long way since the last time I tried it seriously. I’m now using NixOS exclusively on all my work and home machines.