使用 NixOS/Nix 的「最佳实践」是什么?

如题。

  1. 对于那些基于 FHS 开发的/发行的软件,有哪些成熟的经验方法将它们移植到 Nix 上?
  2. 为 Nix 打包时有哪些注意事项?

我大概花了2周的时间,想把环境迁移到guix去。但是最后失败了,你说的FHS就是一个很大的原因。

因为GUIX为了保证隔离性和可复现性,所以需要为包做wrap。 比如用脚本wrap 执行文件的环境变量,patch interprete。就比较麻烦,而且有个risk, 如果移植的程序内部有调用一些/usr/bin/ls(硬编码进程序的) 这样的命令的话,就会比较麻烦。这种我暂时没想到解决办法。

另外guix 是不用systemd的,所以如果仍然是硬编码的而且没有源码的话,同样会比较头疼(nix好像是用systemd的?可能没这个问题)。

这些问题可能是可以被解决的,但是我一想到以后我找个软件要是没有guix的支持,我就得自己去做一遍这些patch的话,我就感觉很恐怖所以就放弃了…

你用Nix的话,可以参考一下。另外,guix因为有编译过程,所以安装软件可能没arch和ubuntu这种快, 不知道nix是不是这样的。

nix也有编译过程,大体上guix有的问题,nix也有(nix用systemd)

网络问题,打包问题,文档混乱问题 用起来成本太高了

我个人感觉的话,直接用 docker 跑应该是个最佳选择

网上也有人问过类似的问题

我自己尝试过构建一个 shell,参考官方文档最终还是放弃了。。。

https://nixos.org/manual/nixpkgs/stable/#sec-fhs-environments

没用过 Docker,有点疑惑:

  1. Docker 属于虚拟化技术,个人使用会不会性能开销太高了?
  2. 听说 Docker 已经被 GFW 了,甚至连镜像站都给 ban 了。 :fearful:

你都用nix了,还考虑啥GFW啊 少不了从github直接拉文件下来,现编译,还有nixos的缓存机器国内直连也不太好

FHS 的话,nixos 有提供fhs环境,例如vscode 就有fhs包,可以安装任意插件,例如clangd插件,它会下载clangd的二进制包

注意事项,没啥注意事项,能编译过就基本没问题

运行二进制文件: 在一开始如果遇到没有移植的软件,看看有没有像 flatpak,appimage打包的版本。实在不行,用 steam-run 运行下。

日常开发:遇到的问题一般是动态链接库问题,可以用 LD_LIBRARY_PATH 环境变量解决。(一些二进制无法运行也可能是动态链接库问题)。ldd命令非常实用。

遇到问题多上Nix论坛。

  1. 我查了一下资料,Nix 的发明者现在已经被 Nix 社区赶出去了…

https://lwn.net/Articles/971973/

https://save-nix-together.org/

不用担心, 咱不是还有 HW 主导的开放原子开源基金会 搞了个国产绿色版 docker 镜像站吗? :yum:

2 个赞

这个概念在 Nix 里面叫什么名字?

好像叫 steam-run?

这个名字……好像最开始是用来解决 Nix 运行 Steam 的问题的?

哦哦,好像是的,我以前搞的已经忘记了 :joy: 刚刚查了一下,好像更新的做法是用 nix-ld,你可以查一下 NixOS wiki 看看。

  1. 对轻度使用最重要的:Nixpkgs更新极快,而Guix的官方channel简直是滚动更新仓库之耻
  2. Nix下载channels/flake inputs就是直接拉取仓库快照, 而Guix——我不知道它具体是怎么实现的——似乎使用了某种“递归”过程?(注意两者的官方channel都是自包含的)在网络都没问题的情况下前者比后者快得多
  3. Nixpkgs允许非自由固件上架,Guix不允许。不过对于foreign distro来说没什么区别
  4. Nix工具链比Guix更丰富,比如各种xxx2nix;Nix语言作为DSL甚至比Guile受到更多的编辑器支持,就算不支持,直接用vim编辑也比Guile更方便(不过这里是Emacs论坛……所以这个优势应该反过来?)
  5. Flake系统便于去中心化,尽管Nix社区本身相当中心化;双重版本锁定机制也比guix describe更灵活

嗯,你说的前面那些点挺不错,但“Nix社区本身相当中心化”我不认同,而且nixos社区一直宣扬的包多的观点,也就笑笑,它那个分包的粒度,包不多才奇怪呢 nix很多人都是闭门造车,论中心化远不如aur这种,即使同样有nur,也没多少包 很多人自己打包都只在自己的nixos配置中使用,很少有人会单独提取出来作为单独包使用

另外,nixos的社区都已经把nix的作者踢出社区了,没考证过,我记得是在哪个群组有人提了一嘴

我在打包上还是新手,不过根据个人经验来说:

  1. 没有。在Nixpkgs仓库一查你会发现无数种绕过FHS的方法。除了一些特殊情形,这些方法所基于的“原语”无非是find, grep, awk, sed四件套以及编译环境自带的几个bash函数(比如 substituteInPlace)。学习这些东西的最好方法是生成式人工智能。
    • 用flake和nix命令,把channel和nix-命令当作不存在,这样才能获得现代包管理器(conda, cargo, yarn, pkg.jl, etc)的体验。
    • 不要指望文档。 绝大多数包,唯一的文档就是代码注释和PR评论。所以有任何疑问首先看相关包的代码。另外NixOS Wiki上有大量dirty hack(比如直接在/nix/store中搜索、调用甚至改动文件),属于严重的抽象泄漏,与Nix的设计背道而驰。不要信。
    • 虽然说不要指望文档,但Nixpkgs Manual还是必须逐字阅读。有大量稀奇古怪的设计光看别人打的包根本不可能知道(比如nativeBuildInputs并不是单纯的“构建时依赖”,而是包括了Nix-specific的东西,如wrapQtAppsHookhash属性不知道的时候不能随便乱填,而是只能填固定的几个占位符)
    • 如果构建脚本完全自制,那么需要手动创建$out目录,mkDerivation不会帮你创建。
    • mkDerivation的大部分(所有?)属性都会变成环境变量,但是不要太依赖这个功能,因为它无法调用其他环境变量,比如out
2 个赞

有一说一,作为导火索的Anduril事件在我这个中国人看来有些可笑——这伙人都直球向欧盟要饭了,居然对军火商的赞助如此在意。可能是“君子远庖厨”吧。

1 个赞

只用新命令的话,好像是完全没法儿命令式安装包了,只能靠声明式,修改 nixosConfigurations 和 homeConfigurations,感觉和这些现代包管理器没什么关系啊🥲

“现代”的意思是project-specific和lock file,也就是在项目根目录建一个flake.nix,里面内容参照模板,然后自动生成flake.lock,开发时使用nix shellnix develop

至于imperative用法,有nix profile,效果和nix-env类似,而且用法更符合惯例、更便于记忆,(据说还有别的好处,但是我从来没手动调用过nix-env,所以忘记了),应该说新命令才更适合新手入门和迁移。但是nix profile没法触发一些包的适配机制,所以还是建议尽量使用project-specific配置。我个人是用profile在NixOS上安装“非必要”应用程序,因为安装、卸载、清除历史记录都无需sudo,也可以随意使用unstable分支、自定义构建而不干涉系统主干。和flatpak结合,相当于变成Android式的应用管理策略了。

另外补充一点,关于nix命令和flake的“实验”性质,这不是由于技术不成熟、实现不稳定或设计方向不确定,而只是社区治理问题在产品上的体现罢了。实际上Nix(“CppNix”)整个软件都已经在事实上锁定在2.18版本了(更高的版本不被Nixpkgs接受为默认),开发者想不稳定都没办法,所以还是可以放心使用的。

1 个赞