Jakob Gillich Personal blog

NixOS

After reading about it so many times, I finally tried NixOS. Never heard of it? Definitely check out their web site, but if you’re not into functional programming, you probably won’t understand what it is all about. At least I didn’t, until I tried it. And it blew my mind. But let me break it down for you.

NixOS

NixOS is basically a regular Linux distro, it runs on the desktop as well as on the server. What makes NixOS special is the way it is configured. The entire system is based on a single configuration file at /etc/nixos/configuration.nix. NixOS configuration uses the Nix programming language, having programming knowledge is not required, but makes things easier. Nix is also a package manager, but more about that later. Unlike configuration management tools like Ansible, there is zero state in the NixOS configuration. If you remove a service from your NixOS configuration, it is gone, there is no uninstall step.

Traditional configuration management works by checking the system state and performing the required actions. For example, installing a service usually goes like this:

  • Manually write the configuration file
  • Ensure required packages are installed
  • Ensure the configuration is correct
  • Ensure the service exists
  • Ensure the service is started

On NixOS, you add this to your configuration:

services.syncthing =
  { enable = true;
    user = "jakob";
  };
  • There is not installation. enable = true; implies that.
  • There is no separate configuration, it can be done in the NixOS configuration

If you install something on NixOS, nothing is actually written to paths like /usr or /bin. Instead, every package and every service gets its own file system structure at /nix/store. The actual system that you are running is made of symlinks to these directories (and to each other). Why is this the best thing ever? Whenever you change something in your configuration, NixOS creates a new copy of your system, again made of links to /nix/store. These copies are called profiles, and they occupy almost no space. When ever you’ve made an error in your configuration, you can just roll back to any previous state. This is especially great when you’ve made changes that result in you being unable to boot, you can simply select a older profile during boot.

Nix

Nix is a package manager and not specific to NixOS, it works on other Linux distributions, too. Its syntax is very similar to other package managers, installing something is as easy as:

nix-env -i git

But of course it’s not exactly like other package managers. First of all, it can operate in multi-user-mode, which means you don’t need root access to install software. Just like NixOS, Nix uses profiles and is able to roll back installations.

Something that is probably unique to Nix is the ability to override packages and to create derivatives. By default, Nix uses binary packages, but you can make changes to packages and it will then compile the package with your changes. To give you a example, you can use this to create your own version of vim with the plugins you need. This means you don’t have to manually manage and update plugins, Nix can do it for you. These overrides can be done in your system-wide configuration or on a per-user basis at ~/.nixpks/config.nix.

There is also an incredible amount of packages for NixOS. Often, smaller Linux distributions have a hard time maintaining so many packages, but that doesn’t seem to be the case for Nix. I actually found that there are more packages in Nix than there are in Fedora - not based on the raw numbers, but on what I use.

Updates in Nix are based on channels, which are just releases, but you can mix them without problems. I’ve wanted some newer versions of some packages, so I downloaded the nixpkgs repository and ran:

> sudo -s nix-env -i rkt -f ~/devel/nixpkgs/
replacing old ‘rkt-0.8.0’
installing ‘rkt-0.10.0’

Yes, it’s that simple. What is also simple is installing non-free software. Nix has packages for all the drivers and Steam, you just need to allow them in your config:

nixpkgs.config.allowUnfree = true;

Problems

The way NixOS works offers many advantages, but there are problems. Any software that relies on standard paths does not work on NixOS. Any bash script that uses #!/bin/bash does not work on NixOS. The included packages have all been changed to ensure they work, but anything you get from elsewhere might not work. Sometimes when you just need to do this one thing, and do it quickly, NixOS can get in the way. I personally just use Docker for anything that’s not Nix-compatible, but I’m also working on packaging a few things. This would be a valid reason why there are so many packages - packaging is easy, but you need it to really get anything working.

I also have to say, there is not a lot of information about NixOS on the web. I’ve been reading more of the nixpkgs source code than anything else, but that’s not a bad thing. I feel like it’s actually a strong point about Nix, the source is easy to understand and it is never outdated. But it is really not a system where you can just search for you problem and find the answer in some shitty forum.

One example for problems I’ve had is setting the GTK+2 theme. It defaults to the very ugly Raleigh. But how do you change it? To set the theme, you need to set GTK2_RC_FILES to the theme path - which is hard on Nix because the regular /usr/share doesn’t exist. And there wasn’t a single mention of this problem on the web - which really surprised me. The solution is, you might have guessed it, just a little bit of configuration:

environment.variables =
  { GTK2_RC_FILES = "${pkgs.gnome_themes_standard}/share/themes/Adwaita/gtk-2.0/gtkrc"; };

That being said, there’s great documentation that covers a lot of topics.

Solutions

I love the way the NixOS configuration works.I can write the configuration once and deploy it on any machine or even to a container. Or do it the other way around, run the server configuration in a container on your workstation.

There is also nixops to deploy NixOS machines to the various cloud providers.

To wrap this up - NixOS is awesome and solves a lot of problems, you should try it.