Why you should never ever use NixOS

Andrei Maksimov

Andrei Maksimov

2.3
(8)

This article describes my personal experience of using NixOS in the development and production environments in 2018. Maybe, something has been changed since then, but I’ll still keep this article published for the broader IT community. Please, let me know the comments section on your use case and experience for this operating system.

So, this is what has been stated in 2018 at the NixOS website:

DevOps-friendly. Declarative specs and safe upgrades make NixOS a great system for DevOps use. NixOps, the NixOS cloud deployment tool, allows you to provision and manage networks of NixOS machines in environments like Amazon EC2 and VirtualBox. (c) NixOS.org

Today, when I’m updating this article, is 2021 website states:

Reproducible builds and deployments. Nix is a tool that takes a unique approach to package management and system configuration… (c) NixOS.org

NixOS at 2021

I’m happy that finally, they decided to remove “DevOps friendly” because from my personal point that is an incorrect statement.

Well, in 2018, I was a “lucky” guy. I had no choice and had to spend most of my working time on NixOS automation. To that moment in time, I had more than 15 years of experience using different Linux distributions, and by the time I published the first version of this article, I had more than 6 months of NixOS experience. And most of my experience with NixOS was a bad experience.

Why you may want to use NixOS

Like any other purpose-built solution it NixOS has its own niche. That’s what Google Trends tells us about it:

I like that someone decided to solve the problem of “reproducible builds and deployments.” This is a tough problem to solve. But from my personal point of view, this problem should be solved by well-established processes, not by the tool.

Determinism

First of all:

In … computer science… a deterministic system is a system in which no randomness is involved in the development of future states of the system. A deterministic model will thus always produce the same output from a given starting condition or initial state. (c) Wikipedia

So, determinism is the main feature of NixOS. It is provided to you by the system design. Basically, Nix and NixOS are trying to guarantee that you’ll get the same version of any software package from the Nix repository.

For example, you may install Nix tools on Linux and macOS, and the package you’re installing should be the same. But from my experience in 2018, it was not true.

And there were lots of examples of such behavior, for example, fetchgit and fetchFromGitHub functions:

These issues are in the open state from 2017 and 2018. I removed additional examples because someone removed them from GitHub.

Reasons not to use NixOS

Again, this is my personal view on the problem space, and it can not be affiliated with the company or project where I’m currently working. Let’s get started.

Small community

Sure, there are lots of enthusiasts who are playing with NixOS by installing it on their workstations at VMs, but in comparison with Ubuntu, CentOS, Debian, or RedHat:

NixOS vs other Linux distributions

That means you will not be able to:

  • Get fast or enterprise grade support
  • Hire people to manage it

Documentation

The official documentation has been improved since 2018, when I initially started this article, but at that time, it was awful or absent. I did not spend too much time reviewing it in 2021. So, I encourage you to try doing it yourself to make your own conclusion. I’ll keep this part for consistency.

Configuration language (Nix)

Nix is a functional language that defines NixOS system configuration. If you’re coming from the OOP world, it might be tough to understand this language.

But if you do have no choice, as I did in 2018, the best way to learn Nix is to go to swallow Nix pills.

Software management

The derivation is a way of describing software and its dependencies in NixOS.

Each derivation describes the software, plugin, or library.

Here’s an example of Nginx derivation:

{ stdenv, fetchurl, openssl, zlib, pcre, libxml2, libxslt
, gd, geoip
, withDebug ? false
, withStream ? true
, withMail ? false
, modules ? []
, version, sha256, ...
}:

with stdenv.lib;

stdenv.mkDerivation {
  name = "nginx-${version}";

  src = fetchurl {
    url = "https://nginx.org/download/nginx-${version}.tar.gz";
    inherit sha256;
  };

  buildInputs = [ openssl zlib pcre libxml2 libxslt gd geoip ]
    ++ concatMap (mod: mod.inputs or []) modules;

  configureFlags = [
    "--with-http_ssl_module"
    "--with-http_v2_module"
    "--with-http_realip_module"
    "--with-http_addition_module"
    "--with-http_xslt_module"
    "--with-http_geoip_module"
    "--with-http_sub_module"
    "--with-http_dav_module"
    "--with-http_flv_module"
    "--with-http_mp4_module"
    "--with-http_gunzip_module"
    "--with-http_gzip_static_module"
    "--with-http_auth_request_module"
    "--with-http_random_index_module"
    "--with-http_secure_link_module"
    "--with-http_degradation_module"
    "--with-http_stub_status_module"
    "--with-threads"
    "--with-pcre-jit"
    # Install destination problems
    # "--with-http_perl_module"
  ] ++ optional withDebug [
    "--with-debug"
  ] ++ optional withStream [
    "--with-stream"
    "--with-stream_geoip_module"
    "--with-stream_realip_module"
    "--with-stream_ssl_module"
    "--with-stream_ssl_preread_module"
  ] ++ optional withMail [
    "--with-mail"
    "--with-mail_ssl_module"
  ]
    ++ optional (gd != null) "--with-http_image_filter_module"
    ++ optional (with stdenv.hostPlatform; isLinux || isFreeBSD) "--with-file-aio"
    ++ map (mod: "--add-module=${mod.src}") modules;

  NIX_CFLAGS_COMPILE = [ "-I${libxml2.dev}/include/libxml2" ] ++ optional stdenv.isDarwin "-Wno-error=deprecated-declarations";

  preConfigure = (concatMapStringsSep "\n" (mod: mod.preConfigure or "") modules);

  hardeningEnable = optional (!stdenv.isDarwin) "pie";

  enableParallelBuilding = true;

  postInstall = ''
    mv $out/sbin $out/bin
  '';

  meta = {
    description = "A reverse proxy and lightweight webserver";
    homepage    = http://nginx.org;
    license     = licenses.bsd2;
    platforms   = platforms.all;
    maintainers = with maintainers; [ thoughtpolice raskin fpletz ];
  };
}

Do you like it?

If yes, then great!

You’ll not be able to live in the NixOS world without writing something like this daily.

Nix packages

NixOS GitHub repository will be your second home, where you’ll be looking for examples of Nix expressions, configuration approaches, and other examples.

Configuration management

System state and configuration are described in a special file configuration.nix. It’s like an entry point to an endless amount of functions and dependencies for your OS.

If you want to customize something in the operating system, be ready; you’ll need to write your custom systemd service to do that. And, yes, service configuration files also need to be declared using Nix expression language.

All standard system configuration files, for example, /etc/fstab are generated by a weird code of Nix derivations.

As soon as derivation is processed, its outputs like configuration files will be read-only.

Side note from the future myself: sometimes it might be an excellent idea to prevent people from changing system configuration, especially manually, but it’s another story 😁. I think that the NixOS system configuration is tough and time-consuming.

Kernel upgrade

It is impossible to upgrade the kernel from version “A” to version “B” without rebuilding the whole world. A new kernel will bring the whole set of system packages and their dependencies with it. So, the upgrade process might take a little while.

Cloud support

In 2018 Nix was not ready for a cloud. At all. I was facing the following issues with NixOS 18.03 at AWS:

  • OS was not booting from the AMI
  • OS was not supporting newest AWS instance types (like m5.*, for example)
  • NixOS 18.03 was not able to resize your EBS volume

If you’d like to give it a try now, here’s a link to the official NixOS AMIs for AWS, which I was able to find after visiting the NixOS forum.

For any reason, Google does not show them at the top search results for the “nixos aws ami” query.

Google search results for NixOS AWS AMI

Cache

To speed up software installation in NixOS, the community provides you with Nix Binary Cache, where they put everything they’ve built successfully. Every version of every derivation.

Problems start happening when you are spinning up your personal cache, which is used, for example, to store your proprietary build artifacts. You always need to keep an eye on the community channel version you’re using as a base for your builds. And yes, your own cache size will also grow extremely fast!

During one year of Nix experience, I observed how some very talented developers started using Nix binary cache to cache everything possible. For example, NPM or Yarn packages.

Reproducible builds will cost you lots of storage space because you’ll be storing everything literally.

Security

Some people are thinking that the NixOS deterministic approach of dealing with software is very secure. Maybe yes, it is really not possible to hijack the build results once the derivation has been built. But… You always need to pay for it…

First of all, see the last sentence in the previous section where I mentioned the extremely fast-growing Nix binary cache.

Windows support

In 2018 I wrote, “Just forget about it.”

In 2021, when I was updating this article, I found Nathan Bijnens’s post “Nix on Microsoft Windows 10” describing how to run Nix in WSL.

I did not try it.

Please, feel free to share your thoughts on this in the comments below if you did. As this article is quite popular, other people would appreciate your comments.

System requirements

Running NixOS requires lots of CPU power to build OS derivations and lots of disk space to store multiple versions of software dependencies. Way more than you need in traditional Linux distros.

But again, this is a tradeoff of the deterministic approach and reproducible builds.

What should I do if we already invested in NixOS?

If this operating system and how it solves the problem of predictable builds suit your needs and you’re comfortable with all challenges you’re facing, fine.

For all the other people, I’d say that the migration from NixOS might be extremely painful.

In any case, it should be a business decision what to do about it, but if you’re not too far away, I’d suggest the following:

  • Try to change a technology stack as soon as possible
  • Do not listen anybody
  • Do not reinvent the wheel
  • Migrate and forget

What to do next

Well, thank you for your time and desire to read this port. Now, I can suggest you go ahead, do your own Google (re)search, summarize your own thoughts around the topic and make your own weighted decision.

In addition to this, I would suggest you give it a try and run something simple, for example, a WordPress blog in the NixOS.

Positive experience? Great!

Negative? You got the point.

And like in any other situation in your life, think twice when you’re deciding to invest your time or money in something.

Additional external resources

How useful was this post?

Click on a star to rate it!

Average rating 2.3 / 5. Vote count: 8

No votes so far! Be the first to rate this post.

As you found this post useful...

Follow us on social media!

We are sorry that this post was not useful for you!

Let us improve this post!

Tell us how we can improve this post?

Subscribe to our updates

Like this article?

Share on facebook
Share on Facebook
Share on twitter
Share on Twitter
Share on linkedin
Share on Linkdin
Share on pinterest
Share on Pinterest

Want to be an author of another post?

We’re looking for skilled technical authors for our blog!

Leave a comment

If you’d like to ask a question about the code or piece of configuration, feel free to use https://codeshare.io/ or a similar tool as Facebook comments are breaking code formatting.