Which problem does Nix solve?

(I hope it’s okay to ask this here. It’s more of a Nix question.)

I’ve just finished reading this https://engineering.shopify.com/blogs/engineering/what-is-nix
and I cannot figure out which problem Nix is actually solving.

Could somebody explain that, please?

Read https://edolstra.github.io/pubs/phd-thesis.pdf .

1 Like

I hope I don’t have to actually read a PhD thesis to figure this out. :wink:

3 Likes

Reading up to p.14 should be enough. The rest is more of set of technical details of the implementation which are interesting but perhaps not part of a straight answer to your question.

1 Like

Perhaps a more personal answer will improve my other blunt answers :upside_down_face: .

For me, Nix is an Awesome package manager with the advantage of an (almost) real programming language with which the packages are defined and thus it enables anyone to put any type of change they wish to a package.

For example, a while ago I noticed a bug in a program which hadn’t had a release for a while but it was still actively developed. The bug has bothered me and I reported it upstream and they’ve fixed it in a week or two. I didn’t want to wait for another release so I wanted my system to use the patched package. Back at the time, I was using Arch Linux and I was frustrated by the fact I have to download a PKGBUILD file, edit it and run several commands to make my system actually use it. With Nix, it was as simple as adding an overlay to my configuration.nix with patches attribute. With a traditional package manager, even if you make the effort to “override” the original package definition, you still might end up with an unpatched version of the package after a generic system update.

This + Awesome community + a way to configure your entire system configuration declaratively + a real repo for PRs (vs Arch’s patches mailing lists or whatever and a old school website such as bugs.archlinux.org/ ) is the best ground for the best Linux experience there could be.

8 Likes

Nix is solving several problems, but which ones you care about depends on your domain(s).

If you’re a tinkerer, Nix gives you a declarative and reproducible way to manage your system which is pretty important if you plan to maintain your changes. I can be pretty fearless about upgrading and patching packages because I can just roll back if I break things.

If you’re a project maintainer, Nix solves having to maintain a text list of libraries in your README for contributors to install. You can just use Nix+Direnv and they’ll automatically receive any libraries that whatever the project commit depends on, meaning if you go back to an old commit it just works, or if you fetch master and it has new dependencies, it also just works.

If you’re part of a devops team in a company you can use the above for the same reason, quicker onboarding. You can also use it to build sparse and intentionally layered docker images for smaller update deltas. You can also use it to cache packages on your build server reliably, e.g. so you don’t have to rebuild/download postInstall libraries that NPM packages like to do (and caching node_modules isn’t a great idea).

You also avoid the YAML/JSON mess of mapping fields to functions in a language like Go, Nix is a programming language so you can just do stuff there to avoid config boilerplate. Although Dhall is IMO a better fit here because it’s typed, but Nix is still better than YAML/JSON.

8 Likes

As others said, Nix can solve different problem, depending on your needs.

My usage of Nix is pretty modest: I am using NixOS as my operating system of choice on my personal laptop. For me, NixOS was a meaningful upgrade over Arch Linux. The main benefit for me is that the system just works:

  • I can’t accidentaly break it by sudo make install of a random package, because / is read only
  • More generally, before NixOS I had a “reinstall OS to clean things up” routine which I run couple of times a year. NixOS just doesn’t get into a bad state, and I am basically running the same instance of NixOS on my third laptop in a row.
  • Even if I had to install NixOS on a new laptop, I just drop my config and get essentially a clone (though, dotfiles in ~ and plasma configuration sadly still require some manual tinkering)
  • There’s build-in rollback mechanism. Even if I do a bad upgrade, I can just boot an older version of the system, without doing anything specific for rollback. Rather, I need to run explicit gc to clean up older configuration.

Despite being super stable, NixOS is also pretty flexible, and you can easily mix stable base with unstable pieces:

  • You can either run bi-yearly released stable channel or a rolling-release unstable channel
  • You can run stable channel and pick specific packages from unstable channel, without fearing that you’ll end up in a DLL hell
  • If unstable channel is not enough, it’s relatively easy to fully override specific packages to, eg, versions build from an unreleased master branch. Again, without fear of contaminating you system with different versions of libraries or breaking it in other interesting ways
  • Finally, it’s pretty easy to send patches to nixpkgs to upgrade existing software or add new
9 Likes

So, I’ve read the first 14 pages now. Good read, thanks for the link! Here is the motivation section:

1.3. Motivation
From the previous discussion of existing deployment systems it should be clear that they
lack important features to support safe and efficient deployment. In particular, they have
some or all of the following problems:
• Dependency specifications are not validated, leading to incomplete deployment.
• Dependency specifications are inexact (e.g., nominal).
• It is not possible to deploy multiple versions or variants of a component side-by-side.
• Components can interfere with each other.
• It is not possible to roll back to previous configurations.
• Upgrade actions are not atomic.
• Applications must be monolithic, i.e., they must statically contain all their depen-
dencies.
• Deployment actions can only be performed by administrators, not by unprivileged
users.
• There is no link between binaries and the sources and build processes that built them.
• The system supports either source deployment or binary deployment, but not both;
or it supports both but in a non-unified way.
• It is difficult to adapt components.
• Component composition is manual.
• The component framework is narrowly restricted to components written in a specific
programming language or framework.
• The system depends on non-portable techniques.
The objective of the research described in this thesis is to develop a deployment system
that does not have these problems.

Some of these would need some elaboration and since I don’t know, if anybody wants to explain how NixOS solves these - shorter than a thesis - that would also be nice.

1 Like

@Shou Let me summarize what I am reading into this:

  1. Stuff doesn’t break. - This is not really a huge problem for me, I do have a bit of a re-install once a year workflow, though. Reproducible way to install. I am not sure if and how this works but if this allows me to easily install virtual machines, Raspberry Pi images and whatnot with a specific set of features it does sound pretty cool.
  2. Automatically maintaining dependency lists. That sounds great. I am not sure how it works yet but I love it already!
  3. I think this is what I called Reproducible way to install. above, right?
  4. Ok, I’m not sure I prefer Nix or Dhall over YAML/JSON. At least I know the latter two. :wink:

I could write my story, but for all the relevant things it is identical to the one of @doronbehar! Haha!

The following doesn’t apply to Nix directly, but to NixOS. It may still be relevant :slight_smile:
I’m a sysadmin and thus not directly interested in the benefits a developer experiences.
But as @doronbehar pointed out with NixOS you can configure your whole system declaratively.
This has various implications which may not be obvious:

  • Installing a new system is extremly quick. All you basically need to do is partition your disk, download your existing config, run the installation, end of story
  • You can have multiple systems with exactly the same configuration. Always. Puppet, Ansible, and also a part of Docker is trying to do something which is already included with NixOS.
  • You can split your configuration and use only one part of the same configuration for another machine. Or you can share complex configuration snippets for others to use. This leads to stuff like Nixos Mailserver or the slightly more complex but very powerful nixcloud-webservices. Instead of 2+ hours of setting up a mailserver, automated certificate generation, etc. I have one file of 20 lines, which I import into my server configuration and all that’s left to do for me is setting the proper DNS on the DNS server.
  • The biggest selling point for me to use it on my desktop devices: I see exactly what is configured - extremly quickly. For example I can skim over my laptops configuration.nix and see that I configured a swiss german keyboard, that I enabled powertop, sound (pulseaudio with some extra configuration to be able to also use Jack) & bluetooth, that I use some Apple Hardware specific boot options, etc. Gathering all these machine specific information from your /etc/ directory is extremly difficult. And even then you might not know which of the configuration was done by you or is just standard.
3 Likes

I’ve used NixOS for only a few months now, so I haven’t figured out all of the fancy things yet, but for me there are a couple things which are super easy in nix and a total pain with other package managers. Some that haven’t been mentioned so far are:

  • I can just run nix-shell -p somePackage and I get a shell with access to a certain package. This is really useful when you need conflicting versions of packages in different situations (like with wine and wine-staging for games), or if you want to compile some program but you don’t want to install all build dependencies permanently on your system.
  • If I need to change the compilation flags of some package, I can simply add one or two lines to my config.nix file, and nix takes care of recompiling, getting dependencies and so on for me.
1 Like