Using the global registry to create the initial flake.lock

I’m on NixOS unstable and through my configuration, I’ve pinned the specific revision of nixpkgs my system builds off of to the global flake registry. I want to re-use that revision when I create new flakes (that consume nixpkgs as an input) to avoid having multiple revisions of nixpkgs scattered across my various flakes (and thereby my /nix/store).

I am aware that you can have the flake use the global registry by doing inputs.nixpkgs.url = "nixpkgs", but this produces an impure lock file that doesn’t use the correct nixpkgs version on other machines (unless this has changed in recent versions?).

What I’m hoping to do (in theory, and if possible), is to create a flake with a valid nixpkgs flake reference, and during the creation of the initial lock file, use the revision information from the global registry to sync nixpkgs to the exact revision used by the global registry.

To demonstrate the idea visually, I want to be able to create a flake with the same branch ref as my NixOS system:

# flake.nix
{
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; # not trying to use flake registry at all
  };

  outputs = { … }: {
    # <omitted>
  };
}

Then, I want to be able to invoke some nix3 command that can create the initial flake.lock file with the same revision information as what is saved in the flake registry:

# flake.lock
{
  "nodes": {
    "nixpkgs": {
      "locked": {
        "lastModified": "FROM_REGISTRY",
        "narHash": "FROM_REGISTRY",
        "rest_FROM_REGISTRY": "<omitted>",
      },
      "original": {
        "owner": "NixOS",
        "ref": "nixos-unstable",
        "repo": "nixpkgs",
        "type": "github"
      }
    },
    "root": {
      "nixpkgs": "nixpkgs"
    }
  },
  "root": "root",
  "version": 7
}

Is this possible at all? If so, how? If not, maybe I should post it as a feature request.

Make your flake.nix as normal, and for the lockfile you can probably use something like

myrev=$(nix flake metadata nixpkgs --json | nix run nixpkgs#jq .locked.rev)
nix flake update --override-input nixpkgs github:NixOS/nixpkgs/$myrev

NB /etc/nix/registry.json is not the global registry, that’s the system registry. I’m not nitpicking - you can use the global registry in flake inputs, but not the system registry. nix registry - Nix 2.32.7 Reference Manual

1 Like

Beautiful snippet of code, thank you very much! Also, thanks for clarifying the global vs system registry. I didn’t even realize that nix tries to download a global registry, I had thought there was only the local and system registries. I learned something new from that.

Minor fix to the above snippet though, jq needs the -r flag to prevent the quotes from causing issues. Otherwise, the snippet works exactly as I was imagining.

$ nix flake update --override-input nixpkgs $(nix flake metadata nixpkgs --json | nix run nixpkgs#jq -- -r '.locked.rev')
1 Like

I thought the same thing can be accomplished by setting
nix.registry = {
nixpkgs.flake = nixpkgs;
};
In your configuration. Can you explain the difference, please?

That sets the system registry in /etc/nix/registry.json which you cannot use in flake inputs, like I said.

That’s already very helpful. But I should have made my question more concrete, I’m sorry. I’m relatively new to nix and my goal here is to understand when you would want the nix.registry setting compared to your approach?
I’ve encountered this as an answer to the same question OP was asking, which I had too at the time, so I set that option and forgot about it.

But you seem to be implying that it’s not a solution?

Edit: to add to this, I’ve never verified that setting this does lock the initial flake to the same revision the system is using. But I know that it does give you outputs from the same rev when you run nix shell nixpkgs#somepackage

I’ll restate it, then: it is not a solution.
Flake inputs will still use nixpkgs from the global registry, which is using the nixos-unstable branch.
nix will ignore anything you have set in your system registry when it comes to flake inputs; the system registry is only used by the CLI, which is why I provided a solution that uses the CLI.

1 Like

Hmm on further reflection, a simple nix flake update --override-input nixpkgs nixpkgs should also work? I don’t use nix currently so I can’t confirm.