在懒猫上实现应用持久化(二):Nix 安装配置工程化指南

隔壁老王

发布于1天前
还没想好签名

面向懒猫平台(LZCBox)x86_64 系统的 Nix 持久化方案
从能用到长期可运维的工程化脚本。
脚本地址:
https://github.com/lazycat-contrib/nix_persistence_manager.sh

{CD1E1EEE-9748-49BB-AED3-BBB7C1DA1A58}.png

一、前言:这次我们要解决什么问题?

第一篇《Nix 安装与配置完全指南》已经证明了路线可行:

  • 用 bind mount 把持久目录映射到 /nix
  • 用单用户模式安装 Nix
  • 重启后依然可恢复使用

但当你开始长期使用,会出现更"运维化"的需求:

  1. 无人登录也要能启动服务 — 只靠 .profile 的挂载触发不够。
  2. 从旧配置迁移到新规范要可重复 — 手动迁移容易遗漏。
  3. 网络环境复杂,安装路径要弹性 — 代理与离线包都要支持。
  4. 变更要可预演、可回退 — 先看将执行什么;不需要时也要可清理。

所以本篇目标是把整套流程工程化为一个脚本:

  • 既支持全新安装(推荐使用官方安装器获取最新版本)
  • 也支持旧配置迁移
  • 并且把自启动、离线、代理、清理都纳入同一工具

二、为什么在懒猫上必须这么设计?

1. 懒猫系统强调稳定底座

懒猫采用只读系统镜像 + Overlay 的架构:

  • 核心系统稳定、可恢复
  • 不能把长期状态寄托在"临时可写层"上

2. /etc 不是可靠持久入口

所以要把可持久化配置放在允许长期保存的区域(例如 /root),并优先采用用户域机制(systemd --user)。

3. 为什么坚持 /nix 用 bind mount

Nix 生态里大量工具默认使用绝对路径 /nix/store。bind mount 的优点:

  • 对程序来说,/nix 仍是"真实路径入口"
  • 对存储来说,数据实际落在持久目录

4. 为什么要双触发(.profile + nix-ready

  • .profile:照顾交互登录体验,登录后自动准备环境。
  • nix-ready:作为硬兜底,任何命令执行前都能先检查并补挂载。

三、准备工作

  1. 已通过 SSH 登录懒猫,并拥有 root 权限。
  2. 将脚本放到 /root
mv nix_persistence_manager.sh /root/
chmod +x /root/nix_persistence_manager.sh

四、快速开始(推荐方式)

一键安装,使用官方推荐版本:

/root/nix_persistence_manager.sh --official

带代理:

/root/nix_persistence_manager.sh --official --proxy http://172.18.0.1:10809

脚本会自动:

  1. https://nixos.org/nix/install 获取官方安装脚本。
  2. 解析出当前推荐版本(如 2.34.7)和 SHA256。
  3. 下载、校验、安装。
  4. 配置 bind mount、profile、systemd 服务。
  5. 清理官方安装器产生的冗余配置(.profile 冗余行、fish 配置)。

五、脚本能力总览

脚本文件:nix_persistence_manager.sh(约 830 行,仅支持 x86_64-linux)

能力说明
全新安装--official 自动获取官方推荐版本
迁移配置--migrate-only 迁移到隐藏持久目录
bind mount自动维护 /nix 挂载
nix.conf生成并维护 Nix 配置
辅助工具nix-ready / nix-gc / nix-doctor-lite
systemd 服务nix-bind.service 自动挂载 + linger
代理支持--proxy 统一代理出口
离线安装--tarball--offline-dir
预演模式--dry-run 仅打印不执行
清理回退--cleanup / --cleanup --purge-data

六、详细教程

第一步:先做预演(强烈建议)

/root/nix_persistence_manager.sh --dry-run --migrate-only

提前确认目录、挂载、systemd 操作是否符合预期。

第二步:安装(推荐使用官方安装器)

# 推荐:自动获取官方最新版本
/root/nix_persistence_manager.sh --official

# 带代理
/root/nix_persistence_manager.sh --official --proxy http://172.18.0.1:10809

# 已有 nix 时强制重装
/root/nix_persistence_manager.sh --official --reinstall

其他安装方式

本地离线包

/root/nix_persistence_manager.sh --tarball /root/nix-2.34.7-x86_64-linux.tar.xz

离线目录

/root/nix_persistence_manager.sh --offline-dir /root/offline-packages

脚本会自动在目录内查找 nix-*-x86_64-linux.tar.xz

手动指定 URL + SHA256

/root/nix_persistence_manager.sh \
  --download-url https://releases.nixos.org/nix/nix-2.34.7/nix-2.34.7-x86_64-linux.tar.xz \
  --sha256 <SHA256值>

第三步:迁移已有环境(如果之前已手动安装过)

/root/nix_persistence_manager.sh --migrate-only

它会:

  1. 探测旧数据来源(/root/nix_persistent、旧 /nix 挂载等)。
  2. 同步到新隐藏目录(默认 /root/.local/state/nix)。
  3. 配置 bind mount、profile、systemd 服务。

第四步:开机无人登录也能跑(systemd --user)

/root/nix_persistence_manager.sh \
  --migrate-only \
  --app-service-name my-nix-app \
  --app-exec '/root/.nix-profile/bin/your-binary --flag'

脚本会:

  1. 生成 nix-bind.service(先确保 /nix 可用)。
  2. 生成 app service(依赖 nix-bind.service)。
  3. 自动检查并尝试 loginctl enable-linger root

七、.profile 结构说明

安装完成后,.profile 结构如下:

# ~/.profile
if [ -n "$BASH_VERSION" ]; then
    if [ -f "$HOME/.bashrc" ]; then
        . "$HOME/.bashrc"
    fi
fi

# >>> nix-persistence profile.d loader >>>
if [ -d "/root/.profile.d" ]; then
  for _p in "/root/.profile.d"/*.sh; do
    [ -r "$_p" ] && . "$_p"
  done
  unset _p
fi
# <<< nix-persistence profile.d loader <<<

nix-bind-mount.sh 内容:

# 挂载 /nix
if ! mountpoint -q "/nix"; then
  if [ -L "/nix" ]; then rm -f "/nix"; fi
  mkdir -p "/nix"
  mount --bind "/root/.local/state/nix" "/nix" 2>/dev/null || true
fi
# source nix profile(设置 PATH 等)
if [ -e "/root/.nix-profile/etc/profile.d/nix.sh" ]; then
  . "/root/.nix-profile/etc/profile.d/nix.sh"
fi
# 添加辅助工具到 PATH
case ":$PATH:" in
  *":/root/.local/bin:"*) ;;
  *) export PATH="/root/.local/bin:$PATH" ;;
esac

关键点:

  • 挂载和 nix profile 初始化都在 nix-bind-mount.sh 里完成。
  • 官方安装器添加的冗余行会被自动清理。
  • fish 配置(nix.fish)会被自动移除(懒猫只用 bash)。

八、验证与日常使用

# 验证挂载
findmnt /nix

# 验证 Nix
/root/.local/bin/nix-ready nix --version

# 查看服务状态
systemctl --user status nix-bind.service

# 垃圾回收
/root/.local/bin/nix-gc

九、清理与回退

# 仅清理脚本管理产物(保留 Nix 数据)
/root/nix_persistence_manager.sh --cleanup

# 彻底清理(包含持久化数据)
/root/nix_persistence_manager.sh --cleanup --purge-data

十、常见问题

Q: 安装时提示 "xz not found"

脚本会自动安装 xz-utils。如果网络不通,可提前手动安装:

apt install -y xz-utils

Q: 遇到 .../deleted 报文

表示之前 /nix 的挂载源目录 inode 已被删除。建议:

umount /nix || umount -l /nix
# 找到仍有 store 数据的旧目录
for d in /var/roothome/nix_persistent /var/roothome/.local/state/nix /root/nix_persistent; do
  if [ -d "$d/store" ] && [ -n "$(ls -A "$d/store" 2>/dev/null)" ]; then
    rsync -aHAX "$d"/ /root/.local/state/nix/
    break
  fi
done
mount --bind /root/.local/state/nix /nix

Q: 官方安装器提示 "install Nix as root is not supported"

这是官方安装器的警告,单用户模式下可以忽略。脚本使用 --no-daemon 参数以单用户模式安装。

Q: 如何查看当前安装的版本

/root/.local/bin/nix-ready nix --version

十一、总结

在懒猫平台上做 Nix,核心不是"装上就行",而是"长期稳定可运维"。

这套方案的关键价值:

  1. 尊重平台边界 — 不污染系统底座。
  2. 保证 /nix 语义稳定 — bind mount。
  3. 同时覆盖交互与无人值守场景 — profile + systemd user + linger + nix-ready。
  4. 在真实网络条件下仍可部署 — 代理 + 离线 + 校验。
  5. 有预演和回退路径 — dry-run + cleanup。
  6. 自动获取官方最新版本--official 无需手动选择版本。

评论

0

暂无评论

说点什么呢~
收藏
2
0
0