打造 NixOS 开发环境 (1):为什么选择 Nix

本文首发于:我的个人博客

NixOS,一个用户评价两极分化相当严重的 Linux 发行版。

最近一个星期,我终于下定决心尝试在旧笔记本上安装使用 NixOS,打算将开发环境彻底迁移到这个声明式配置的操作系统上。事实上,从我的个人经验来看,配置使用 NixOS 的难度比我原先预想的要小,最终达到的效果十分令我满意,我终于开始理解为何知乎、Reddit 上不少资深 Linux 用户最后选择 NixOS"养老"了。NixOS 的声明式配置和原子化特性,完美解决了我多设备维护和更新的痛点。

这篇文章将作为后续一整个系列的开篇,详细讲述我选择尝试 NixOS 的目的和核心考量,以及从宏观角度谈谈这个操作系统适合的用户画像。


1. 问题描述

虽然说我觉得自己其实是有一定的 Linux 使用经验的,之前体验过多个不同的发行版,但从个人开发环境的角度说,除非有特殊的项目需要,我大部分的开发环境都在主力 Windows 笔记本上。

实际上,绝大多数时候 Windows 环境配置还是很容易的,对于资源比较充裕的语言和开发工具,支持 Windows 哪怕麻烦也值得尝试去做,绝大多数情况下往往不存在什么问题。但当我开始研究一些相对小众的语言,如 Haskell,或者涉及到底层 C 编译器的问题时,Windows 的解决方案要么不够简单优雅,要么完全不可能。手边有 Linux 开发环境就显得尤为重要了

当然,你可能说这完全可以通过虚拟机和 WSL 配合完成。一方面,使用这些解决方案对日常携带的笔记本电脑有着不低的性能要求;另一方面,对一些特殊的开发需求,比如 GUI 软件开发,想要理顺开发环境同样是不轻松的。

考虑到我自己手边有一些相对老旧硬件,我当时非常自然的想法是把这些多年前淘汰下来的设备利用起来,把一些非 CPU 密集型任务迁移到这些设备上,同时通过物理机使用 Linux,倒逼自己提升 Linux 的实际使用能力。

事实上,我大一的时候就是这么做的,在家和学校各有一台配合使用的 Linux 设备,并将相当一部分开发环境从 Windows 主力机上迁移了出去。

但后来放假的时候又遇到了两个问题:

其一,在一台设备上配置好的环境,换到另一地的另一个设备 上工作时,自然发现完全没有同步配置。很多东西要么自己维护一个自动化配置脚本,要么就必须自己手动再踩坑配置一遍,完全是时间的浪费;

其二,在一地的时候另一地的设备处于不使用状态。对于个人开发机而言,选取滚动发行版并尽量追新软件是一个自然的选择,但滚动发行版的一个重要使用准则就是要紧跟发行版更新,长期不更新的设备突然更新可能会出现各种依赖解析错误

我之前碰到过长期不更新 OpenSUSE Tumbleweed 再次更新后的 Python 依赖版本冲突问题,虽不致命,但很多时候被破坏的环境也要花不少时间修复,这在我看来同样是时间的浪费。对我一些使用 Arch Linux 的朋友而言,长期不更新的设备进行更新,往往体验会更"刺激"一些。

于是我开始思考:有没有一种解决方案,能够实现开发环境的一劳永逸 呢?至少,它应当在极大程度上降低切换设备的维护成本,并尽可能把开发环境的痛点问题提前暴露解决

于是,我注意到了 NixOS。


2. 为什么选择 NixOS

事实上,NixOS 通过其高可复现性的特征,帮助我达成了"配置跟着人走"的目的,可以灵活决定更新的方式和频率。

我们来看看对于上文提到的两个问题,NixOS 的解决方式:

关于"配置跟着人走"的需求,NixOS 让我实现了通过前期打磨一套系统层、用户层和具体项目的配置文件 ,把整个操作系统中的各组件和开发环境清晰地、声明式地描述出来,这套配置文件是可以通过 git 版本管理跟着人走的。这意味着,换一台设备,只需安装系统时对硬件相关配置稍作调整,就可以实现环境的完美复刻。

关于滚动更新和长期停机更新的矛盾问题,NixOS 提供的解决方案同样很令人满意。即使用 Unstable 源,在 A 设备上能正常构建的配置,B 设备即便一段时间未更新,升级时也基本不会出现依赖冲突问题。即便真的有问题,NixOS 的原子化升级特性也可以兜底,确保了系统不至于陷入"升级了一半"这种尴尬境地,开发者有充分的时间慢慢排查配置错误。

总而言之,对于我自己特定的需求而言,NixOS 是一个远优于其他方案的解决方案。


3. NixOS 适合所有人吗?

NixOS 是一个适合我的选择,但这个发行版适合所有人吗?尽管我非常喜欢这个发行版,我仍然不觉得这是一个适合所有人的解决方案。原因有以下几点:

  • NixOS 并不简单。这显然不能完全称之为一个新手友好的发行版,我个人建议是至少要有一种别的发行版的使用经验,熟练使用命令行排查问题,对 Systemd 有着基本的了解,这种情况下迁移到 NixOS 的过程才会相对顺滑;
  • Nix 是一门函数式语言。这门语言其实语法很简单,官方文档看两个小时基本就能学个大概,但是毕竟需要一点函数式思维。如果你接触过 Clojure、Haskell 等函数式语言,上手 Nix 会相当简单。
  • NixOS 无法遵守 FHS 标准。为了达到 NixOS 无与伦比的可复现性,你会发现许多 Linux 系统目录内都是向 Nix store 内的只读软链接,而不是像传统发行版那样的真实文件。这个问题并非无解,绝大多数时候主要是开发者在打包一些软件 (尤其是闭源软件) 需要头疼,对终端用户是无感的。但如果你有特殊需求必须依赖 FHS 标准,NixOS 很可能不是一个方便的选择,需要你深入理解 Nix 打包软件的方法。

当然,如果你是一位 Linux 资深用户,我认为学习使用 NixOS 是完全值得的。

我一直觉得,一些需要付出一定的初始学习成本,但是后期可以获得高回报 的技能、工具都是值得学习 的,也就是坚持长期主义 。之前学习 Rust 语言,强迫自己适应内存安全的代码规范是如此;练习双拼输入法,提高博客写作效率也是如此;而 NixOS,我觉得是在操作系统层面提供的一个类似的"长期主义"路径


这篇文章将作为一个系列文章的开篇,我将在后续文章中继续分享我是如何打造基于 NixOS + Niri 窗口管理器的桌面环境,使用 Flake 和 home-manager 分别管理系统层和用户层配置,开发环境配置,以及探讨一下在部署时 Nix 和 Docker 容器化技术关系等问题。

如果你同样对多设备开发环境感到困扰,或者单纯对 NixOS 的设计哲学感兴趣,欢迎关注我,也欢迎与我随时交流!

相关推荐
华强笔记1 小时前
Linux内存管理系统性总结
linux·运维·网络
十五年专注C++开发2 小时前
CMake进阶: CMake Modules---简化CMake配置的利器
linux·c++·windows·cmake·自动化构建
phoenix09812 小时前
ansible部署lnmp-allinone
linux·运维·ansible
winds~3 小时前
【git】 撤销revert一次commit中的某几个文件
linux·c++
iY_n3 小时前
Linux网络基础
linux·网络·arm开发
phoenix09814 小时前
Linux入门DAY27
linux·运维·服务器
♞沉寂6 小时前
信号以及共享内存
linux·c语言·开发语言
egoist20236 小时前
【Linux仓库】进程创建与进程终止【进程·柒】
linux·运维·服务器·进程创建·写时拷贝·进程终止
大锦终6 小时前
【Linux】文件系统
linux·服务器·c++