I am a GNU/Linux user since 1996. During the first months, I tried to install Red Hat several times. Then, for four years, I loved to do everything from scratch with Slackware. After that, I decided to use Debian in 2001 as a first step to become a Debian Maintainer. Finally in 2019, after 18 years using Debian for everything including workstations, laptops, servers and containers I made a full switch to NixOS.
NixOS is a distribution with novel concepts including:
- Native configuration as code using a uniform language: NixEL.
- Reproducibility between the specification and the software installed.
- Full rollbacks, even if a libc or kernel update fails.
- Multiple versions of the same packages can coexist for several non-privileged users.
- An insane quantity of prepackaged software: >40K.
- The package manager works on top of most Linux distros and OS X.
This post will cover in detail why I made the switch despite my previous track record and the extreme difficulty for an old software engineer now converted into a manager.
First, I illustrate my experience with Slackware Linux. Second, I present the reasons why I moved to Debian and stuck to it for many years. Third, I describe a couple of incidents and day to day situations that led me to the Nix discovery. Fourth, I explain how to transition to it. Finally, I summarize the main points and present some reflections for the future.
My first love was Slackware, a distribution that forced me to do everything by hand because of its pretty basic package management system. During 1995 the internet connections in Medellín, Colombia, were awful. Downloading a Linux installer using a 28.8 Kbps modem needs patience and money. Through IRC, I managed to meet someone in town that sold me the current Red Hat and Slackware installers. Strangely Red Hat didn't work, and Slackware famous for being hard, ran smoothly. After that moment, my long trip to do everything from scratch began. For each application and its dependencies, I needed to:
- Download the upstream source.
- Read the upstream documentation.
- Back up configuration files.
- Document my tweaks for future use.
Mostly, I moved software from one place to another for years.
Near the year 2000, I planned to switch to a project that followed a similar development process as the Linux kernel and recently improved his already large and mature package management system: Debian. This project had clear guidelines to contribute, a bigger community, a broader software ecosystem, homogeneous documentation, and the most advanced dependency management I had ever seen. Everything became clear: less time downloading, compiling, installing, configuring software, or its dependencies. Just one command and everything arrived at my machine as expected. How not to become part of it? I fell in love again, and this time for a long time.
During all these years, my friends and I became Debian Maintainers, taught at universities, built a company, helped customers, made a private custom distribution, and became hobbyists during nights and weekends with the power of Debian, however, perfection was not even close. It was versatile, mature, stable, and relatively easy to handle in scale to solve several types of problems. However, despite using tricks such as preseeding or cfengine, each installation became what is now known as a snowflake, a unique piece of technology. If you wanted to install the same server, you still would need manual steps that inevitably never gave you the same result. You moved one thing, and another was broken. A minor software update silently occurred, and something that worked before didn't work anymore. Moving software was not only a complicated and expensive business but also a very fragile one.
In 2016, a discrepancy between software versions used to build an estimation was the root cause of financial disaster for a project. We had been using CLOC since 2012 to measure the source code size of an application that would be security tested. With this output, during the presales stage, we estimated the price following a simple formula. During the execution phase, we detected an inconsistency in the size of the application currently under test. As we went deep, we realized that different CLOC versions were in use. Again, a problem related to moving software.
Then I found a strange tool called Nix, that with its companion set of packages called Nixpkgs, could erase the problem from the face of the earth. This tool could be installed easily on every Linux, allowing us to maintain the OS anarchy policy that we had until now. Nevertheless, it would enable us to deliver the same piece of software to every possible person within seconds. The tool looked weird at the beginning:
- Installing everything under
/nix(store) is a clear violation of the FHS.
- Most files are symbolic links pointing to weird names in the store.
- To install a single package for all the users, you need to change a configuration file and “rebuild” the OS.
- Each change creates a new entry on GRUB.
- The disk gets full pretty fast, thus requiring a garbage collection process to remove the waste.
Despite how strange it was, it promised predictability, a requirement that was not always fulfilled, even for Debian, the distro with the strictest build policies and the better maintenance guidelines.
To personally experiment all the promises of this exotic beast, I decided to use it in my daily job gradually. From 2016 to 2017, I ran a Nix subsystem on top of my Debian Unstable. Then, I moved to NixOS over a virtual machine to find the workflows that fitted my needs and to get confidence to throw away my old habits. In 2019, I moved my host OS to NixOS unstable.
When I was forced to change my laptop twice, I received the validation of all Nix's promises were real. Just formatting the new machine, cloning the git repo that contained the full OS configuration, and waiting for the “build” process to end, gave me the same machine that I had before. Like in functional programming languages, it seemed like a pure function: the same output for the same input with no side effects. Since last year, the times of wasting effort moving software or catching bugs related to it are over.
After installing and using GNU/Linux for almost 24 years, I would say that the time spent moving software from one place to another is enormous. The implications of bad deployments are even more significant than the wasted engineering effort. Debian is still a pretty fantastic piece of work of the OSS community, and its habits are enrooted in many of us. However, Nix and its friends are solving the deployment problem tackling it from its roots. They are redefining assumptions and bringing a new era of stability, predictability, and joy for engineers. I hope that Nix prospers and will be the standard for many distributions in the future.
The main problem in achieving this future lies in the attraction of top developers from other distributions. Gentoo, Arch, and Debian are pretty vibrant communities and full of highly skilled developers. However, many of them remain skeptical when confronted with concepts like derivations, generations, store, rebuild, rollback, infra as code, non-GUI installation, flakes, etc. They think that Docker, Ansible, or other similar tools solve the same problem quickly, but the only way to convince them is by raising awareness of how much time they are still wasting moving software.