![](/nixos-and-flakes-book.webp) # Nix 与 NixOS 简介 Nix 是一个声明式的软件包管理器,用户需要通过某些配置声明好期望的环境状态,而 Nix 负责达成这个目标。 > 简单解释下什么是「声明式配置」,它是指用户只需要声明好自己想要的结果——比如说希望将 i3 桌面替换成 sway 桌面,Nix 就会帮用户达成这个目标。 > 用户不需要关心底层细节(比如说 sway 需要安装哪些软件包,哪些 i3 相关的软件包需要卸载掉,哪些系统配置或环境变量需要针对 sway 做调整、如果使用了 Nvidia 显卡 Sway 参数要做什么调整才能正常运行等等),Nix 会自动帮用户处理这些细节(当然这有个前提,就是 sway 跟 i3 相关的 nix 包设计良好)。 而基于 Nix 包管理器构建的 Linux 发行版 NixOS,可以简单用 OS as Code 来形容,它通过声明式的 Nix 配置文件来描述整个操作系统的状态。 一个操作系统中有各种各样的软件包、配置文件、文本或二进制的数据,这些都是系统当前的状态,而声明式的配置能够管理到的,只是其中静态的那一部分。 而那些动态的数据(比如说 PostgreSQL/MySQL/MongoDB 的数据),显然是无法通过声明式配置管理的(总不能每次部署都直接删除掉所有未在配置中声明的新数据吧)。 因此 NixOS 实际也只支持通过声明式配置管理系统的部分状态,上面提到的各种动态数据,以及用户 Home 目录中的所有内容,都不受它管控(所以在你将 NixOS 切换到上一个版本时,NixOS 不会对它们做任何操作)。 但是用户的 Home 目录中实际包含了许多重要的配置文件,用户当然会希望能使用 Nix 将它们给管理起来。 另一个重要的社区项目 [home-manager](https://github.com/nix-community/home-manager) 就填补了这块缺失,它被设计用于管理用户 Home 目录中的配置文件以及用户级别的软件包。 因为 Nix 声明式、可复现的特性,Nix 不仅可用于管理桌面电脑的环境,也有很多人用它管理开发编译环境、云上虚拟机、容器镜像构建等等,Nix 官方的 [NixOps](https://github.com/NixOS/nixops) 与社区的 [deploy-rs](https://github.com/serokell/deploy-rs) 都是基于 Nix 实现的运维工具。 ## 为什么选择 NixOS? 好几年前就听说过 Nix 包管理器,它用 Nix 语言编写配置来管理系统依赖,此外基于 Nix 包管理器设计的 Linux 发行版 NixOS,还能随时将系统回滚到任一历史状态(额实际上这个回滚有些限制,前面提过了)。 虽然听着很牛,但是不仅要多学一门语言,装个包还得写代码,当时觉得太麻烦就没研究。 但是我最近在使用 EndeavourOS 时遇到了一系列麻烦事儿,花了大量的精力去解决,搞得我精疲力尽。 我仔细一想,遇到的这些问题归根结底还是系统没有版本控制跟回滚机制,导致出了问题不能还原,就必须得各种查资料找 Bug,手动修复系统状态。 所以我就决定干脆换成 NixOS. 切换到 NixOS 后,我对它那是相当的满意,腰也不疼了,背也不酸了... 最惊艳的是,现在我可以通过仅仅一行命令,就能在一台全新安装的 NixOS 主机上还原我的整个 i3 桌面环境以及所有我的常用软件! NixOS 的回滚能力给了我非常大的底气,我现在再也不用怕把系统搞挂了(挂了直接回滚就恢复了),于是我又在 NixOS 尝试了许多新鲜玩意儿! 在以前 EndeavourOS 上我肯定是不太敢这么玩的,因为万一要是把系统玩出问题了,就必须手动修复系统状态,那可是相当麻烦。 这就是我选择 NixOS 的原因。