Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nix profiles are hard to reproduce #7965

Open
bobvanderlinden opened this issue Mar 4, 2023 · 5 comments
Open

nix profiles are hard to reproduce #7965

bobvanderlinden opened this issue Mar 4, 2023 · 5 comments
Labels
feature Feature request or proposal new-cli Relating to the "nix" command

Comments

@bobvanderlinden
Copy link
Member

The main selling point of Nix is reproducibility. However, since nix profile doesn't expose its manifest.json it is far from trivial to reproduce the same profile on a different system. manifest.json seems like a good candidate to be used in nix shell, home-manager and NixOS. This gives the best of both worlds: imperative CLI, declarative and shareable configuration. For example, something like this would be nice to have:

$ nix profile install nixpkgs#cowsay
$ nix profile export manifest.json
# On another system:
$ nix profile import manifest.json
# Or:
$ nix shell --manifest manifest.json
# Or in home-manager:
{
  home.profiles.main = lib.importManifest ./manifest.json;
}

This is similar to what Guix is already doing: https://guix.gnu.org/manual/devel/en/html_node/Writing-Manifests.html

@thufschmitt thufschmitt added feature Feature request or proposal and removed bug labels Mar 4, 2023
@thufschmitt
Copy link
Member

Re-labeling as feature because it's not a bug per se, more a potential extension (although I agree that it would be great)

@roberth roberth added the new-cli Relating to the "nix" command label Mar 16, 2023
@nixos-discourse
Copy link

This issue has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/flakes-as-a-unified-format-for-profiles/29476/1

@ilyagr
Copy link

ilyagr commented Jul 18, 2023

As very much a newcomer to Nix, I also found this surprisingly difficult.

I ended up installing home-manager just to have a "profile" I can share between computers. I'm not sure I'd recommend that -- it tries to do way more than that, and I'm not sure whether that helps or hurts more for my personal config.

Once I learn how, I would probably try moving from home-manager to using my own flake. I'm surprised it's not trivial to write a flake that just says "get these packages from nix-pkgs and install them". I'm guessing it's not going to be too bad once I understand flakes, but I expected this to be just a matter of copying a few lines of obviously correct code.

@lf-
Copy link
Member

lf- commented Jul 21, 2023

This is a regression compared to the old cli in which you can just use:

nix-env --install --remove-all --file blah.nix

where blah.nix returns an attrset with the packages you want to install. (also, if the manifest format prevents you writing Nix expressions to define what to install it really loses out on many benefits of Nix)

@iFreilicht
Copy link
Contributor

iFreilicht commented Aug 10, 2023

@lf- declarative configs still works in the new CLI:

You can run nix profile install --file blah.nix just like before, though there is no --remove-all right now, so you have to run nix profile remove '.*' first if you want the exact same state. I assume blah.nix looks something like this:

{ pkgs ? import <nixpkgs> {} }:
with pkgs; [
    direnv
    asdf-vm
    grc
    autojump
]

You can also put a declarative configuration into a ~/my-env/flake.nix like this:

{
  outputs = { self, nixpkgs }:
    let
      system = "aarch64-darwin";
      pkgs = nixpkgs.legacyPackages.${system};
    in {
      packages.${system}.default = pkgs.buildEnv {
        name = "my-env";
        paths = with pkgs; [ direnv asdf-vm grc autojump ];
      };
    };
}

Which you can then install with nix profile install path:/home/my-user/my-env (note that you need to use an absolute path for the following update procedure to work), or git init, nix flake lock, git add . and git commit to make it a git flake and then install it with nix profile install ~/my-env.

If you then change anything in that flake.nix, you just need to run nix profile upgrade 0 (or '.*' or whatever the index of this package is, maybe 'my-env' if #8678 gets merged) to bring your environment into a state that can be reproduced anywhere.

See "Transitioning from imperative to declarative package management with nix alone" (Nix Discourse) where I posted more detailed info about this.


However, this is not what this ticket is about. If you have the foresight and put in the effort, a declarative profile already allows you to get a declarative profile. But if you just used nix-env -iA or nix profile install to install packages like you would with a regular package manager, and then you want to reproduce it on a different machine, you're out of luck.

I think a potential and more generalized solution to this might be #8806 in conjunction with a PR that creates profile generations via a single derivation. Right now, a profile doesn't have a deriver (i.e. a derivation it was built from):

$ nix derivation show ~/.nix-profile
error: '/nix/store/xd3nsvdgam01ms497wmy93zdasrxl4wp-profile' does not have a known deriver
$ nix-store -qd ~/.nix-profile
unknown-deriver

Both nix-env and nix profile cobble their profiles together manually, not by creating a derivation first and then building that. If they did create a derivation, the above feature request would enable you to export that derivation with all its inputs at once and rebuild it on any other machine, as long as that machine has the same system triple.

Hm, ok, maybe a dedicated mechanism that is system-agnostic is the better solution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature Feature request or proposal new-cli Relating to the "nix" command
Projects
None yet
Development

No branches or pull requests

7 participants