9

Nix and NixOS, my pain points

 2 years ago
source link: https://remy.grunblatt.org/nix-and-nixos-my-pain-points.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Posted on: Fri 23 December 2022

I have been a user of Nix (a “reproducible” package manager) and NixOS (the Linux distribution based on this package manager) for almost two years. I use it in a personal and professional context. In this article I will focus on the “pain points” in my use of Nix and NixOS. While there are many positives, the NixOS experience is far from being a smooth ride. I still mostly enjoy using Nix and NixOS, and this article is not about blaming anyone. I’m also a part of the problem, as I could probably participate more actively in the project.

Poor documentation

The documentation of Nix and NixOS is rather poor. To understand how a service or an option works, it is very often necessary to read the source code (`.nix’ files) because there are no explanations in the manual, or the explanations are not very comprehensible.

On this point, the use of GitHub to host project repositories makes this search sometimes difficult. For example, a search on the keyword “pass-wayland” should return a result in the “Code” tab, but it does not, because Github does not index the entire repository (you can check that it is present by using your browser search feature on the all-packages.nix file)

The Nix / NixOS wiki is rarely up to date. It mixes information related to specific versions of nixpkgs (e.g. 22.05, unstable, …) without necessarily specifying which version it is. As it is not an “official” resource, its pages contain many references to the use of third party tools (such as the home-manager program or the cachix service) or non-stable features (such as flakes). Specific configurations are posted directly to the wiki (e.g. https://nixos.wiki/wiki/Sway) without any explanation of the choices made or their specificity, which the declarative aspect of the NixOS configuration tends to encourage.

A porous evaluation

The reproducibility of NixOS / Nix / Nixpkgs is very perfectible. One might think that by default NixOS is ‘reproducible’ (for some definition of reproducible). This is not really the case: two machines that have the same configuration files (/etc/nixos/configuration.nix) can differ widely due to dependency on other configuration files such as ~/.config/nixpkgs/config.nix, the ability to change Nix’s behaviour using environment variables, command line arguments or even due to using different versions of Nix.

Since the Nixpkgs repository (which contains all the recipes related to the packages present in NixOS) is different from the Nix repository (which contains the source code of the Nix package manager), using a specific commit of Nixpkgs is not enough, it is also necessary to pay attention to the version of Nix used, or else regressions might appear. From this point of view, Guix has a better approach in my opinion, a single repository being used for the package manager and the package “recipes”.

Fragile sources

The reproducibility of NixOS / Nix is also only assured if the sources used remain truly accessible. A recent example underlines the fragility of these sources, and the fragility of Nix which does not exploit solutions such as Software Heritage (where Guix does for at least three years). This means, in a scientific context for example, the user, that is to say me, still has to care for source preservation if they wants to be sure five or ten years after they developed their code and used nix, it still runs.

No binary reproducibility

One of the problems with Nix / NixOS / Nixpkgs regarding the backup of these sources is simply the discovery of the sources to archive. Indeed, it is not possible to easily extract the set of dependencies (e.g. URLs used in the recipes of Nixpkgs packages) to archive them, as a certain number of these URLs are only “computed” at evaluation time, which requires to evaluate the whole Nixpkgs set, in all its possible configurations, to make sure that one is actually archiving what needs to be archived (part of this work is currently done by Hydra, but unfortunately broken). And that’s without even mentioning Fixed Output Derivation. It should be remembered that the reproducibility of Nix / NixOS / Nixpkgs is only a reproducibility of the sources: if the sources change, one is warned, but it is not a question of the reproducibility of the binaries (which can change at each build).

This binary reproducibility of Nix / NixOS / Nixpkgs is indeed not really tested, at least not systematically. The website “Is NixOS Reproducible?” points out that the NixOS ISO is 99.77% reproducible, but this is a check on a tiny percentage, less than 2%, of all packages. Again, Guix is much better with stats on all packages in the repository. And even more classical distributions such as Archlinux or Debian are better at this than Nix / NixOS / Nixpkgs ! As of now :

Managing state could be easier

To handle « state », e.g. data that is not software but which is linked to certain software versions, e.g., postgresql data, NixOS uses the system.stateVersion option which specifies how compatible is the state with software versions. For example, for postgresql, the package version depends on system.stateVersion, unless overwritten manually :

      mkDefault (if versionAtLeast config.system.stateVersion "22.05" then pkgs.postgresql_14
            else if versionAtLeast config.system.stateVersion "21.11" then pkgs.postgresql_13
            else if versionAtLeast config.system.stateVersion "20.03" then pkgs.postgresql_11
            else if versionAtLeast config.system.stateVersion "17.09" then mkThrow "9_6"
            else mkThrow "9_5");

Because any module can depend on this stateVersion, this means updating between different stateVersions is harder than it should be, in an ideal world. The NixOS FAQ states (haha) you can update system.stateVersion when :

  1. You have read all release notes starting from your stateVersion.
  2. You have verified all instances of stateVersion in the code in <nixpkgs/nixos>.
  3. You have made all manual interventions as required by the changes previously inventoried.

While reading release notes is ok, verifying the source code of <nixpkgs/nixos>, especially when the Github Search is broken, is less ok. Currently, there is also no policy on how long a given system.stateVersion should be supported. This seems harder than it should be.

Nix and NixOS: it’s all or nothing

When we use NixOS, and we want to use a package that is not available under NixOS / Nixpkgs (which happens quite often), we have only one choice: pack it into NixOS. It is generally not possible to take a shortcut and use precompiled binaries, which means that it is not possible to work with constraints (such as time constraints) on Nix / NixOS, unless you are a motivated enough user to sometimes package several levels of dependencies, which tends to take time. And, of course, because Nix or NixOS are radically different from more classical package management, you can’t really mix them together in a single project and expect to have a good user experience. Using only NixOS is thus not tenable, for me: I need to have access to a second machine, under a more classical distribution. That would also be true on Guix System.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK