如何在nix中记录可重现的配置文件(尤其是来自nix-env)?

bba*_*ker 2 nix

所以,最终开始获得一个稳定的nix环境,我基本上可以完成我的所有开发.Hooray!

现在我想让它具有可重现性,如在yarn.lock中(对于那些熟悉javascript版本中的npm/yarn)或Pipfile.lock(非常类似于Python).

基本上我的想法是,无论何时运行nix-env -if my-env.nix,或者在运行此命令之后,我都有办法生成类似的锁文件,如果它是如何工作的.从这个锁定文件,我可以完全恢复我的nix配置文件,直到确定的安装配置文件的依赖项和子依赖项的版本.在测试出新的改进之后,可以将其检入git或其他任何内容,因此将保持环境记录.

在我看来,这将是Nix最明显的使用案例之一,而且仅仅使用Docker的主要优势之一(尽管两者并不相互排斥),所以如果我错过了一些相关的文档,我会道歉.

Sil*_*ger 6

您可能正在寻找的是这样的shell.nix文件:

let
  pkgs = import (fetchTarball {
    url = "https://github.com/NixOS/nixpkgs/archive/696c6bed4e8e2d9fd9b956dea7e5d49531e9d13f.tar.gz";
    sha256 = "1v3yrpj542niyxp0h3kffsdjwlrkvj0mg4ljb85d142gyn3sdzd4";
  }) {};
in pkgs.mkShell {
  buildInputs = with pkgs; [
    git
    hello
  ];
}
Run Code Online (Sandbox Code Playgroud)

当打电话nix-shell(默认情况下使用该shell.nix文件在当前目录下),你会在与环境git,并hello从具体给出nixpkgs修订.这可以在所有nix用户之间重现(好吧差不多*).我真的可以推荐使用shell.nix文件进行所有开发.

另外,还有一个鲜为人知的-r旗帜nix-env,其中说明了这一点

--remove-all,-r

首先删除所有以前安装的包.这相当于首先运行nix-env -e'.*',除了一切都在一个事务中发生.

您可以有效地使用它来替换有状态~/.nix-profile/manifest.nix.创建一个env.nix包含以下内容

let
  pkgs = import <nixpkgs> {};
in {
  inherit (pkgs) git hello;
}
Run Code Online (Sandbox Code Playgroud)

现在运行nix-env -ir env.nix将准确安装githello其他和删除一切,所以你可以用这个单一的文件复制您的尼克斯-ENV安装.要安装其他内容:将其添加到文件并再次运行该命令.您也可以将nixpkgs固定到上面文件中的特定版本,而不关心您的nix-channel设置(也是有状态的).

编辑:也可以从您的频道和一些特定的nixpkgs修订版中获取一些软件包:

let
  pkgs = import <nixpkgs> {};
  fixed = import (fetchTarball {
    url = "https://github.com/NixOS/nixpkgs/archive/696c6bed4e8e2d9fd9b956dea7e5d49531e9d13f.tar.gz";
    sha256 = "1v3yrpj542niyxp0h3kffsdjwlrkvj0mg4ljb85d142gyn3sdzd4";
  }) {};
in {
  inherit (pkgs) git;
  inherit (fixed) hello;
}
Run Code Online (Sandbox Code Playgroud)

*:nix配置,覆盖和您的系统(Linux/Mac)仍然可以影响这一点.使用import <nixpkgs> { config = {}; overlays = []; }开发来避免这种情况是个好主意.