About single-user Nix installation

Nix1is awesome. Compared to traditional package managers, like yum, portage or apt, it is quality of life improvement. And it is easy to install in parallel to existing system, using this2 script. This script creates single-user installation, where all files are owned by your regular user.

Such setup is fine as long you only want to install pre-built software that is part of Nixpkgs collection, but once you decide to go deeper and write your own package definitions (so called derivations), I strongly recommend to switch to client-server setup.

Once wonderful property of Nix is that built packages are never modified, which makes rollbacks to previous version easy. But in case of single-user setup, there is nothing to stop you (or, more likely, your build script) from accidentally modifying files that are supposed to be read-only. Been there, done that, never again.

By the way, if you already have corrupted your Nix installation, here is remedy:

$ nix-store --verify --check-contents --repair

Client-server setup provides safety net for such accidents: every build process is run as separate non-privileged user. Assuming that you already have single-user setup, switching to client-server is simple:

  1. Change owner of /nix to root:

    # chown -R root:root /nix

  2. Create build group and build users:

    # addgroup nixbld # adduser -S nixbld1 nixbld # adduser -S nixbld2 nixbld

    Nix daemon uses users of nixbld group to perform parallel build of different derivation. Ten users should be more than enough.

  3. Make sure you have NIX_REMOTE environment variable set to value daemon. Following line in ~/.profile would suffice:

    export NIX_REMOTE=daemon

  4. Start Nix daemon somehow. If your distribution uses runit, runscipt for Nix daemon is simple:

    #!/bin/sh
    NIX=/nix/store/wm0vhf0805a7pvqv4adyfjfa2bxm04ax-nix-2.3.2/
    export NIX\_SSL\_CERT\_FILE=/etc/ssl/cert.pem
    export SSL\_CERT\_FILE=/etc/ssl/cert.pem
    exec ${NIX}/bin/nix-daemon

    The hash part wm0vhf... corresponds to latest version of Nix at time of writing on amd64 architecture. Minor adjustments may be needed.

    If your distribution uses openrc init system, init script is very similar:

    #!/sbin/openrc-run
    NIX=/nix/store/wm0vhf0805a7pvqv4adyfjfa2bxm04ax-nix-2.3.2/
    export NIX\_SSL\_CERT\_FILE=/etc/ssl/cert.pem
    export SSL\_CERT\_FILE=/etc/ssl/cert.pem
    
    unset NIX\_REMOTE # VERY IMPORTANT
    
    command=$NIX/bin/nix-daemon
    command\_background=true
    pidfile=/run/nix-daemon.pid

It is essential to make sure that Nix daemon does not inherit NIX_REMOTE variable from your environment, otherwise it will try to connect to itself instead of actually doing work.

If you see that Nix daemon endlessly spawns more processes, that is probably the cause. I am not sure whether it is bug in Nix or in concept of init.d scripts.


  1. https://nixos.org↩︎

  2. https://nixos.org/nix/download.html↩︎