如何配置Nix Store跨多磁盘?将非当前系统世代存至额外磁盘
配置NixOS将非当前系统世代存储到额外磁盘
要实现将除当前启动世代外的所有系统世代转移到额外网络磁盘,同时保证系统不依赖额外磁盘仍可正常启动,可按以下步骤操作:
1. 配置额外磁盘自动挂载
首先确保网络磁盘在系统启动后自动挂载,编辑/etc/nixos/configuration.nix,添加磁盘挂载配置(根据你的磁盘类型调整参数):
fileSystems."/mnt/nix-extra" = { # 替换为你的网络磁盘设备路径或远程地址,比如NFS的"nfs://server/path" device = "/dev/disk/by-uuid/xxxxxx"; # 替换为对应文件系统类型,如nfs、cifs、ext4 fsType = "ext4"; # 网络磁盘需添加_netdev,确保网络就绪后再挂载;cifs需额外添加账号密码等选项 options = [ "_netdev" ]; };
执行nixos-rebuild switch应用配置,验证磁盘是否正常挂载。
2. 编写旧世代迁移脚本
创建脚本用于将非当前世代转移到额外磁盘,并更新垃圾回收根目录,避免根磁盘被旧世代占用。创建/etc/nixos/migrate-old-generations.sh:
#!/usr/bin/env bash # 额外磁盘上用于存储旧世代GC根的目录 EXTRA_GC_ROOT_DIR="/mnt/nix-extra/old-generations" mkdir -p "$EXTRA_GC_ROOT_DIR" # 获取当前启动的系统世代名称 CURRENT_GEN=$(readlink -f /run/current-system | grep -oP 'system-\d+-link') # 遍历所有系统世代,迁移非当前世代到额外磁盘 for gen_link in /nix/var/nix/profiles/system-*-link; do GEN_NAME=$(basename "$gen_link") if [ "$GEN_NAME" != "$CURRENT_GEN" ]; then # 将世代及其依赖复制到额外磁盘 nix-copy-closure --to "$EXTRA_GC_ROOT_DIR" "$gen_link" # 在额外磁盘创建GC根链接,标记该世代不被垃圾回收 ln -s "$gen_link" "$EXTRA_GC_ROOT_DIR/$GEN_NAME" # 删除根磁盘上的旧世代链接(后续垃圾回收会清理对应的store内容) rm "$gen_link" fi done # 执行垃圾回收,清理根磁盘上无GC根的内容 nix-collect-garbage -d
给脚本添加执行权限:
chmod +x /etc/nixos/migrate-old-generations.sh
3. 配置脚本自动运行
为了在每次nixos-rebuild switch后自动迁移旧世代,可将脚本加入系统激活脚本,编辑configuration.nix:
# 导入脚本文件 environment.etc."nixos/migrate-old-generations.sh".source = ./migrate-old-generations.sh; # 配置系统激活时运行迁移脚本 system.activationScripts.migrateOldGenerations = '' ${pkgs.bash}/bin/bash /etc/nixos/migrate-old-generations.sh '';
再次执行nixos-rebuild switch应用配置。
关键注意事项
- 启动独立性:当前世代的所有依赖均保留在根磁盘的
/nix/store中,即使额外磁盘未挂载,系统仍可正常启动,仅无法回滚到旧世代。 - 磁盘兼容性:确保额外磁盘的文件系统支持Nix的硬链接、权限管理,推荐使用ext4、NFS;若使用CIFS,需在挂载选项中添加
file_mode=0755,dir_mode=0755保证权限正确。 - 回滚旧世代:若需回滚到旧世代,需确保额外磁盘已挂载,再执行
nixos-rebuild switch --switch-generation <世代编号>。
内容的提问来源于stack exchange,提问作者Hnus
相关产品推荐
相关产品推荐

