sudo,但首次部署和更新系统配置需要管理员权限。
本页只介绍 NixOS 的部署入口。Docker profile 本身是 Linux 宿主能力,不是 NixOS 专属能力。Ubuntu、
Debian 与其它 systemd Linux 需要安装等价的宿主服务。macOS 用户可以在 OrbStack Linux machine 内运行
NiceEval 和对应的 Linux 宿主服务;Apple container 当前需要独立 NiceEval Provider。具体边界与命令见
让 Sandbox 使用 Docker。
如果任务可以信任 Agent,或者只在一次性 VM 中运行,先阅读让 Sandbox 使用 Docker
选择 Docker socket 或 raw privileged DinD。它们不需要本页的宿主 profile。
前置条件
开始前确认:- NixOS 使用 flake 管理系统配置;
- 宿主使用 systemd 和 cgroup v2;
- 你知道日常运行 NiceEval 的 NixOS 用户名;
- 宿主有足够的 CPU、内存和磁盘留给评估容器。
flake.nix,配置名是 my-host,日常用户名是 alice。请把它们替换成
自己的值。
引入 NiceEval module
在系统配置的flake.nix 中加入 NiceEval input,并把 module 放进主机的 modules:
flake.nix
flake.lock。提交这份锁文件,避免
不同机器在未确认的时间使用不同 module 版本。
声明 profile
在 NixOS 配置中声明一个名为default 的 profile:
configuration.nix
capacity:NiceEval 可以分给评估任务的总量。ephemeralDiskBytes:每个 Sandbox 的 Docker 数据最多占多少磁盘。dockerDataAllocationCount:最多同时有几个 Sandbox 拿到 Docker 数据空间。aggregate:Docker daemon、构建进程、宿主服务和评估容器加起来的硬上限,每一项都不能小于capacity。两者之间的差额留给宿主侧的开销。
backing = "loop-ext4" 会在 /var/lib/niceeval/docker-profiles/default.img 创建一个独立的 ext4 文件系统,并按目录限制磁盘用量。宿主服务从里面给每个 Sandbox 分一个专用目录,挂到 Sandbox 的 /var/lib/docker。不要再给这个路径声明 tmpfs:Sandbox 里的 Docker image 和 BuildKit 缓存应该占磁盘,不应计入宿主机的 Shmem。
这种共享 loop 文件系统只负责运行时的磁盘限额和隔离,不能保存准备步骤的结果。写了 sandboxState.dockerData 的准备步骤,在 niceeval debug 里会显示 Unsupported,每次都真实执行。想让这类步骤下次直接沿用,需要下一节的固定存储配置;准备步骤的缓存规则见选择并配置 Sandbox。
让 Docker 准备步骤下次直接沿用
docker load 这类准备步骤很慢时,你可能希望 Sandbox 里的 Docker image 和 volume 下次直接沿用。这需要另建一个 raw profile,并改用固定大小的存储:
configuration.nix
估算磁盘空间
这份配置预先分配:- 2 个 4 GiB 的运行空间(对应
dockerDataAllocationCount = 2); - 10 份 4 GiB 的只读种子数据(
seedCount = 10),用来保存准备好的 Docker 状态; - 2 份最坏情况下的临时副本。
storage.size = "80G" 在扣除 ext4 元数据和保留块后,剩余可用空间(f_bavail)还要够故障恢复使用。
种子数据不会自动清理。10 份用完后,profile 拒绝保存新的准备结果,也不会覆盖旧的种子。
fixed-image-ext4 只能用于 raw profile。它继续使用现有 daemon 的 DockerRootDir,但把固定存储、宿主配置和日志放在单独的 fixed-image-v1 路径下。rootDir 必须是非根目录的绝对路径,挂载依赖、清单和可写路径都从它推出。
切换到固定存储
切换前,先让这个 profile 完全空闲:- 没有正在运行或排队的 Attempt、构建和容器;
- 默认 daemon 上没有 NiceEval 的代理容器和 Attempt 网络。
loop-ext4 镜像文件。旧镜像、配置和日志都会保留,需要时可以停机回退。
启用固定存储是一次单独的部署操作,不会随 nixos-rebuild switch 或开机自动完成。按顺序启动两个服务:
current 指针原子地切换到新版本。
正常开机时,宿主服务会根据 current 指针找到当前版本,核对 rootDir 所在挂载、外层 ext4、种子登记和校验值,再恢复数据挂载。任何一项对不上时,宿主服务不会开始接收 Attempt。数据盘不存在时,它也不会在根盘上建一个同名目录继续运行。
种子用完之前
种子快用完时,先查看启用服务的状态,里面列出当前可用、保留中、可退役和可回收的容量。更换种子需要手动操作:先停止接收新 Attempt、等现有任务跑完,并在独占锁下发布新版本。 旧版本要先显式退役,才能回收它占的空间。只有既不是当前版本、也不是上一个版本的才能退役。回收之后,这个版本就不能再用来回退。应用系统配置
先检查配置能够求值,再切换系统:alice 加入 profile 的 access group。rebuild 完成后退出当前登录会话并重新登录,让新组
成员身份生效。只在旧 shell 中重新运行命令不会刷新 supplementary groups。
重新登录后检查服务:
active (running)。失败时读取对应 unit 的日志:
验证 profile
进入已经安装 NiceEval 的评估项目,以日常用户运行:list 应该列出 default。doctor 依次检查 profile 描述文件、Unix socket、cgroup、容量、宿主服务、离线资源和一次冷构建,然后启动一个受限的外层容器,并在里面再跑一个 Alpine 容器。全部通过后,这个 profile 才能用于正式评估。
某一项失败时,doctor 会指出是哪一项。先按上一节查看对应服务的日志。
不要用 sudo pnpm exec niceeval ... 绕过权限错误。日常用户无法访问 profile 时,先确认用户名已经写入
accessUsers,再重新登录并重跑 doctor。
在 Experiment 中使用
宿主通过验收后,在 Experiment 的 Docker Sandbox 中引用同一个别名:dockerDataBytes、只读根文件系统,以及其余可写路径的 tmpfs。完整配置见让 Sandbox 使用 Docker。
先用较小的 maxConcurrency 跑一次,再根据 profile 的 capacity 调高并发。跑完后用 pnpm exec niceeval show 在终端查看结果,或用 pnpm exec niceeval view 在浏览器里查看。
更新 module
需要更新 NiceEval module 时,在系统配置仓库更新对应 input,检查 diff 后重新构建:doctor 和实际评估都通过后,再清理旧 generation。