How to pin nix registry nixpkgs to release channel

I had trouble working out how to pin the nixpkgs registry entry to a release channel. I’m posting it here in case anyone else finds it helpful.

On my system, I want the nixpkgs flake to refer to the nixos-21.05 channel (flake url: github:NixOS/nixpkgs/nixos-21.05). But I want this channel to be pinned to a known commit. I want to be able to update this manually.

In order to achieve this, I use the following steps:

  1. Starting off, I don’t have any user registry entries:

    $ nix registry list
    ....
    global flake:nixpkgs github:NixOS/nixpkgs
    ...
    

    At this point, the nixpkgs flake will refer to the master branch in github:NixOS/nixpkgs (which is currently immediately before the 21.11 release):

    $ nix eval nixpkgs#lib.version
    "21.11pre-git"
    
  2. First, you need to add an override to make nixpkgs refer to the nixos-21.05 branch:

    $ nix registry add nixpkgs github:NixOS/nixpkgs/nixos-21.05
    $ nix registry list
    user   flake:nixpkgs github:NixOS/nixpkgs/nixos-21.05
    ...    
    global flake:nixpkgs github:NixOS/nixpkgs
    ...
    
  3. You then need to pin github:NixOS/nixpkgs/nixos-21.05:

    $ nix registry pin github:NixOS/nixpkgs/nixos-21.05
    $ nix registry list
    user   flake:nixpkgs github:NixOS/nixpkgs/nixos-21.05
    user   github:NixOS/nixpkgs/nixos-21.05 github:NixOS/nixpkgs/1e5c35dfbc8e0ad8c35aa1a6446f442ca1ec5234
    ...
    global flake:nixpkgs github:NixOS/nixpkgs
    ...
    

    Now, the nixpkgs flake will refer to this known-good commit on the nixos-21.05 branch:

    $ nix eval nixpkgs#lib.version
    ""21.05pre-git""
    

When you want to bump the pin to the latest version of nixos-21.05, you can use the following command:

$ nix registry pin github:NixOS/nixpkgs/nixos-21.05

Note that you must not accidentally pin the nixpkgs flake. DO NOT DO THIS:

$ nix registry pin nixpkgs
$ nix registry list
user   github:NixOS/nixpkgs/nixos-21.05 github:NixOS/nixpkgs/1e5c35dfbc8e0ad8c35aa1a6446f442ca1ec5234
user   flake:nixpkgs github:NixOS/nixpkgs/9fcf2a8a2cb0f5b78edc8ec7ca877240e7fe3009
...
global flake:nixpkgs github:NixOS/nixpkgs
...
$ nix eval nixpkgs#lib.version
"21.11pre-git"

You can see that here the nixpkgs flake is now pointing back at the master branch. It is unfortunate that Nix doesn’t just “do the right thing” here.


When you want to make the nixpkgs flake point a more recent release of NixOS (the next version will probably be 21.11), you can use the following command:

$ nix registry add nixpkgs github:NixOS/nixpkgs/nixos-21.1`
$ nix registry pin github:NixOS/nixpkgs/nixos-21.11
$ nix registry list
user   github:NixOS/nixpkgs/nixos-21.05 github:NixOS/nixpkgs/1e5c35dfbc8e0ad8c35aa1a6446f442ca1ec5234
user   flake:nixpkgs github:NixOS/nixpkgs/nixos-21.11
user   github:NixOS/nixpkgs/nixos-21.11 github:NixOS/nixpkgs/068984c00e0d4e54b6684d98f6ac47c92dcb642e
...
global flake:nixpkgs github:NixOS/nixpkgs
...
$ nix eval nixpkgs#lib.version
"21.11pre-git"

(Note that this won’t actually work until the nixos-21.11 branch has been created.)

2 Likes

You can also do a similar thing for other release channels / branches.

For instance, here is how to pin a flake pointing to the nixos-unstable channel:

$ nix registry add nixos-unstable github:NixOS/nixpkgs/nixos-unstable
$ nix registry list
user   flake:nixos-unstable github:NixOS/nixpkgs/nixos-unstable
...
$ nix registry pin github:NixOS/nixpkgs/nixos-unstable
$ nix registry list
user   flake:nixos-unstable github:NixOS/nixpkgs/nixos-unstable
user   github:NixOS/nixpkgs/nixos-unstable github:NixOS/nixpkgs/9bf75dd50b7b6d3ce6aaf6563db95f41438b9bdb
...

Now a command like nix shell nixos-unstable#xterm will pull xterm from nixos-unstable at commit 9bf75dd50b7b6d3ce6aaf6563db95f41438b9bdb.

I personally don’t like the global registry, with its imperative way of management.
Instead I remove the global registry and declaratively setup the user registry.

To remove the global registry, set the flake-registry option in nix.conf to an empty registry:

(an empty registry looks like: { "version": 2, "flakes": [] })

To configure the user registry, it is stored in ~/.config/nix/registry.json and I configure it with a home manager module of my own:

And I use it like this:

To declare a pkgs flake (pinned to the nixpkgs of my home flake) and an unstable user flake (on the github’s nixpkgs-unstable branch)

Hope it helps someone :slight_smile:

1 Like

I autogenerate registry from flake inputs using this little module:

1 Like