如何在NixOS MicroVM中配置可用的nixpkgs频道?
问题
我在已安装Nix包管理器的Debian系统上,用microvm创建并运行NixOS虚拟机。虚拟机内的NIX_PATH环境变量默认设置为:
nixpkgs=/nix/var/nix/profiles/per-user/root/channels/nixos:nixos-config=/etc/nixos/configuration.nix:/nix/var/nix/profiles/per-user/root/channels
但虚拟机里/nix/var/nix/profiles/per-user/目录是空的,上述引用的nixpkgs路径根本不存在。请问怎么配置虚拟机,让它构建完成后拥有一个可用的、和构建虚拟机所用的nixpkgs频道一致的引用?
我看到过几个类似问题,但不确定是否适用:
- 如何在configuration.nix中声明式添加NixOS unstable频道
- NixOS:在configuration.nix中设置默认频道
我的flake.nix配置
{ description = "NixOS in MicroVMs"; inputs.microvm.url = "github:astro/microvm.nix"; inputs.microvm.inputs.nixpkgs.follows = "nixpkgs"; outputs = { self, nixpkgs, microvm }: let system = "x86_64-linux"; user = "REDACTED"; vmname = "haskell"; in { defaultPackage.${system} = self.packages.${system}.my-microvm; packages.${system} = { my-microvm = self.nixosConfigurations.my-microvm.config.microvm.declaredRunner; }; nixosConfigurations = { my-microvm = nixpkgs.lib.nixosSystem { inherit system; modules = [ microvm.nixosModules.microvm ({pkgs, ... }: { environment.systemPackages = [ pkgs.ghc pkgs.git (pkgs.haskell-language-server.override { supportedGhcVersions = [ "94" ]; }) pkgs.stack ]; microvm = { forwardPorts = [ { from = "host"; host.port = 2222; guest.port = 22; } ]; hypervisor = "qemu"; interfaces = [ { type = "user"; id = "usernet"; mac = "00:00:00:00:00:02"; } ]; mem = 4096; shares = [ { proto = "9p"; tag = "ro-store"; source = "/nix/store"; mountPoint = "/nix/.ro-store"; } { proto = "virtiofs"; tag = "hometest"; source = "~/.local/share/microvm/vms/${vmname}/shares/home"; mountPoint = "/home/${user}"; socket = "/run/user/1000/microvm-virtiofsd_vm_home"; } ]; socket = "/run/user/1000/microvm-control.socket"; vcpu = 3; volumes = []; writableStoreOverlay = "/home/${user}/nix-rw-store"; }; networking.hostName = vmname; nix.settings = { extra-experimental-features = ["nix-command" "flakes"]; trusted-users = [user]; }; security.sudo = { enable = true; wheelNeedsPassword = false; }; services.getty.autologinUser = user; services.openssh = { enable = true; }; users.users.${user} = { extraGroups = [ "wheel" "video" ]; group = "user"; isNormalUser = true; openssh.authorizedKeys.keys = [ "ssh-rsa REDACTED" ]; password = ""; }; users.users.root.password = ""; users.groups.user = {}; }) ]; }; }; }; }
解决方案
要让虚拟机内的NIX_PATH指向构建时使用的nixpkgs,同时创建对应的频道引用,有两种实用方法:
方法1:声明式设置NIX_PATH并绑定构建用的nixpkgs
在虚拟机配置模块中,直接覆盖environment.variables.NIX_PATH,并将nixpkgs指向系统构建时使用的pkgs路径,同时通过nix.channels声明默认频道:
({pkgs, ... }: { # 保留原有其他配置... environment.variables.NIX_PATH = { nixpkgs = pkgs.path; nixos-config = "/etc/nixos/configuration.nix"; }; # 声明与构建版本一致的系统频道 nix.channels = { nixos = pkgs.path; }; # 让root用户的频道链接指向系统频道 nix.channelSources = { root = [ "nixos" ]; }; })
配置后,虚拟机内的NIX_PATH会直接指向构建时使用的nixpkgs在/nix/store中的有效路径,系统也会自动创建/nix/var/nix/profiles/per-user/root/channels/nixos的链接,解决路径不存在的问题。
方法2:利用Flakes配置默认nixpkgs源(推荐)
因为你已经在用Flakes,更贴合工作流的方式是通过Nix配置指定默认源,同时兼容NIX_PATH:
({pkgs, ... }: { # 保留原有其他配置... nix.settings = { extra-experimental-features = ["nix-command" "flakes"]; trusted-users = [user]; # 允许nix命令使用NIX_PATH兼容模式 use-nix-path = true; # 配置默认nixpkgs源为构建时的版本 registry.nixpkgs.flake = pkgs.path; }; # 可选:为普通用户设置NIX_PATH users.users.${user}.environmentVariables = { NIX_PATH = "nixpkgs=${pkgs.path}:nixos-config=/etc/nixos/configuration.nix"; }; })
这种方式确保虚拟机内使用的nixpkgs和构建时完全一致,无需手动管理频道链接。
验证配置
启动虚拟机后,执行以下命令验证效果:
echo $NIX_PATH ls -l /nix/var/nix/profiles/per-user/root/channels/
应能看到NIX_PATH中的nixpkgs指向/nix/store内的有效路径,且channels目录下存在nixos的链接。
内容的提问来源于stack exchange,提问作者Thomas Koch
相关产品推荐
相关产品推荐

