如何通过shell.nix配置修改nix-build使用的TMPDIR临时目录
问题说明
使用搭配shell.nix文件的nix-shell搭建开发环境时,buildInputs中的依赖包默认在/tmp路径下完成构建,路径剩余空间不足时会抛出error: [Errno 28] No space left on device错误。尝试在启动nix-shell时传入修改后的TMPDIR环境变量、在shellHook中导出新的TMPDIR取值均无法生效,前者仅对nix-shell自身生成的临时文件生效,后者执行时机晚于构建流程,nix-build产生的构建文件仍然存储在/tmp路径下。
当前使用的shell.nix配置如下:
let pkgs = import <nixpkgs> {}; in pkgs.mkShell { name = "something"; buildInputs = with pkgs; [ python38 python38Packages.pytorchWithCuda ]; shellHook = '' ''; }
失效原因
两种常规修改TMPDIR的方案不生效,核心逻辑如下:
nix-build运行在Nix的隔离构建沙箱中,不会继承交互Shell里设置的TMPDIR环境变量,启动nix-shell时传入的TMPDIR仅对进入Shell后运行的普通用户命令生效,无法传入构建沙箱影响构建流程。shellHook是所有依赖构建完成、即将进入交互Shell时才会执行的逻辑,此时构建流程已经结束,在其中导出环境变量自然无法改变构建时的路径配置。
Nix构建时的临时目录由自身专属配置项控制,和系统通用TMPDIR环境变量没有直接绑定关系。
解决方案
临时单次生效
启动nix-shell时通过--option参数直接指定构建临时目录,配置优先级最高,适用于单次使用场景:
# 提前创建好空间充足的目标目录,例如 /data/nix-build-tmp mkdir -p /data/nix-build-tmp # 启动时指定build-dir参数 nix-shell --option build-dir /data/nix-build-tmp
该参数直接传递给Nix构建执行逻辑,单用户、多用户(带nix-daemon)的安装方式均能正常生效。
永久生效
如果需要长期修改临时构建路径,直接写入Nix配置文件即可,无需每次启动追加参数:
- 找到对应Nix配置文件:
- 多用户安装(官方默认安装方式):编辑
/etc/nix/nix.conf - 单用户安装:编辑
~/.config/nix/nix.conf
- 多用户安装(官方默认安装方式):编辑
- 在配置文件中加入如下配置,替换为实际使用的目标路径:
build-dir = /data/nix-build-tmp - 多用户安装需要重启nix-daemon服务让配置生效:
sudo systemctl restart nix-daemon
配置完成后,所有nix-build、nix-shell触发的构建流程都会使用指定目录存储临时文件。
注意事项
- 指定的构建目录所在分区需要预留足够空间,以配置中的
pytorchWithCuda为例,建议预留30G以上空闲空间,避免构建中途再次触发空间不足错误。 - 不要将构建目录设置为tmpfs类型的内存临时分区,否则大体积包构建会占满系统内存触发OOM。
内容的提问来源于stack exchange,提问作者Michaël Witrant
相关产品推荐
相关产品推荐

