How is `NIX_PATH` managed regarding nix channel?

I have this nix channel entry for root user:
nixpkgs https://nixos.org/channels/nixpkgs-unstable
However, my normal user have this in NIX_PATH:
nixpkgs=/nix/var/nix/profiles/per-user/root/channels/nixos which simlinks to nixos-19.09 instead of stable.
I wonder why I have such nixpkgs in NIX_PATH in the first place and why is it different from the one in root’s nix channel.

I want to understand how NIX_PATH is managed in general (behind the scene by nixos tools, so the case when I set its value in a bash terminal is excluded.)

I’ve spent some type debugging what’s up with all that stuff :thinking:

So, nix-channel --list is basically cat ~/.nix-channels.

nix-channel --update creates and modifies a file called ~/.nix-defexpr/channels/manifest.nix.

When environment is set, the following code is executed:

if [ -e "$HOME/.nix-defexpr/channels" ]; then
  export NIX_PATH="$HOME/.nix-defexpr/channels${NIX_PATH:+:$NIX_PATH}"
fi

so, if you have at least 1 user channel updated, you’ll have ~/.nix-defexpr/channels prepended to NIX_PATH. The directory in NIX_PATH means that all it’s subdirectories will be provided to nix commands as “angle-brackets paths”.

But this works only on NixOS. For non-NixOS (at least for multi-user installations), you don’t have this code.

As for list of entries, it is hardcoded both for NixOS and non-NixOS.

For NixOS, it is set to:

          [
            "nixpkgs=/nix/var/nix/profiles/per-user/root/channels/nixos"
            "nixos-config=/etc/nixos/configuration.nix"
            "/nix/var/nix/profiles/per-user/root/channels"
          ];

For non-NixOS it is set to

export NIX_PATH="nixpkgs=/nix/var/nix/profiles/per-user/root/channels/nixpkgs:/nix/var/nix/profiles/per-user/root/channels"

As you see, your assumption about nixpkgs channel is valid on non-NixOS, but on NixOS you are forced to manage a nixos channel instead. So having nixpkgs channel for root brings little value on NixOS.

Worth noting also that nix-env is the only command which doesn’t care about NIX_PATH. Like, you can unset NIX_PATH and nix-env -iA nixpkgs.hello will still work fine. It works because nix-env -i converts ~/.nix-defexpr/channels into an attrset, which you can act over. To make nix-env respect NIX_PATH you should do like nix-env -f '<nixpkgs>' -iA hello

Also, worth noting that nixos channel is used by command-not-found, so you can get it broken if you ever remove nixos channel.

5 Likes