After two years of fighting to keep my home and work laptop config and software in sync with Solus Linux, I gave up. It was a long battle filled with todos, documentation, and re-installation every six months. By giving up, I don’t mean I’ll let them drift apart and create more friction; that would be the worst scenario. Instead, I’m moving away from Solus to NixOS, which entirely solves this problem. Why is this a problem to begin with, though? Linux, in general, is a powerful OS, especially for its customization possibility. You can set it up exactly how you want it by playing around in the configurations, installing packages, and overriding some system settings.
The problems usually come after you’ve set it up how you like it, and there’s an update, changes in packages, or other regular OS changes. Suddenly your customization breaks down. Usually, you’re back to square one and need to figure out how to fix it again, reconfigure and enjoy it for a while. But it doesn’t have to be this way; this problem is precisely one of the issues NixOS solves. It’s a reproducible Linux entirely based on config. There are many creative things this enables, but first, why do I care so much about this? Because it’s been my main problem with Linux since I started using it.
I’ve been using Linux as my main computer OS for the past 10ish years in various forms and flavors. Like most people who switch to Linux, I spent the first couple years moving here and there chasing new shinnies—going around all the big families, Ubuntu, Fedora, SUSE, etc. I always ended up with a system getting more unstable as time went by because of changes I made or the OS package update. After a while, I ended up wiping my computer for a full reinstall, then might as well try this other Linux while I’m there.
After many jump, I finally end up settling on Arch Linux for a couple of years. It’s a very bare-bone distro with just the minimal working packages given to you, after that, you’re on your own (with documentation) to set up the rest. I used and learned Arch for many years; it was great for learning how things worked and how to configure a system nearly from scratch. After a while, though, Arch ended up with the same problem as the others. But this time with a bonus on top of that, reinstalling it is not a small task. To go from nothing to working in Arch takes many hours and trial and error. That is when I initially moved to Solus, which is stable, more user friendly, and easier to set up and reinstall. I lived the last two years with Solus, but today I’m moving away again and not looking back.
NixOS’s main feature is the Nix package manager, a functional package manager in the “write code” way. You create a function to install packages with Nix, not command lines. That way of working is also extended to the full OS, to be consistent and reproducible. The result is that given the same config, you end up with the same system. Many things are going on under the hood to make that a reality, but it’s NixOS main goal.
That feature solves all of the “over time” problems that happen in nearly all computers. Since the config won’t change unless you change it yourself, this ensures the changes you made will stay. On top of that, this also allows me to quickly get two or more computers to share the base system. No more having to manually apply the configuration to my work and home system as I tweak things in one or the other. Just change it in the base configuration, and then both will have the most recent changes.
Having everything being reproducible also makes it very easy to backup. You need to back up the config files and then your data (picture, documents, projects), that’s it. No more need to worry about the configuration list or the packages or other settings, since they’re all in nix config. That sounds pretty much perfect, but how does it work?
Nix package manager
The package manager is where a lot of the magic happens with NixOS. Like everything else, all packages are configurations that tells Nix what to do to get the package installed correctly. A package configuration contains much of the same thing as other packages, dependencies, source or files, compilation step, etc. The main difference comes after that when Nix takes that config and get to work.
Every package it generates comes with a hash of the results, and it’s version. All packages are also self-contained with all the files and configuration inside themselves. Having everything together and hashed will make sure no package will conflict with another version of themselves. That allows Nix to have multiple versions of the same package installed on the system since the hash will be different if there’s a change, and the files are all there.
That makes packages dependencies easy to handle; just ask for the library at whichever version you need. No need to make sure the OS has the correct version or handle fallback if the version is older, everything will be as you required. Nix will look at what is available and download or links the packages for you to compile the application.
The OS itself works pretty much the same way as Nix since it’s based on it to handle all the packages. Like for packages, you have to write your system dependencies, which will be the applications you want installed. You also have to declare all the configuration you want to be implemented, things like network configuration, user configuration, the boot disk, which display manager to use, etc. Like for packages, there is no need to worry about how to do it; for the most part, ask, and NixOS will make it happen for you.
A very interesting side effect of all this is that the OS is also hashed and versioned. That means that if you ever were to create a problem or break some configurations, you can always go back to the previous version, and the issues are gone. Once you’re back to your working system, you can take time to fix the problem and try again; everything is still working fine. Not being left with a half working half-broken system while you’re busy fixing things is a way better experience. That makes NixOS rock solid and stable and great at experimenting since no matter what, you’re just a rollback away from a working system.
Given all the things above, the nix config files are where you’ll spend most of your time when working on the OS. The config file is also not plain text or XML/YAML but very close to a full-blown programming language. It has it’s own syntax and rules, can import other files, do variables and functions, list and boolean, etc. Everything in there is a function with sub-functions that are read and executed. That would probably be the biggest stopper for a new user who is not a programmer or has some programming experience. It’s not a complete showstopper by any means, but it will require even more time and energy for those users to understand how things work.
Once you get a handle on the nix configuration language, the whole thing starts to shine. You can extend the configuration to make them do what you want, add your own or disable others. You can also create your packages for missing applications and plug them with the system package, so Nix does all the work for you. That is the point where everything comes together, and the OS becomes yours to do as you wish. The path to get there can be long, but next, I’ll share some takeaway and things I learn to help to get up to speed.