Skip to content

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 目录中实际包含了许多重要的配置文件(或者叫 Dotfiles),用户当然会希望能使用 Nix 将它们给管理起来。另一个重要的社区项目 home-manager 就填补了这块缺失,它被设计用于管理用户 Home 目录中的配置文件以及用户级别的软件包。

因为 Nix 声明式、可复现的特性,Nix 不仅可用于管理桌面电脑的环境,也有很多人用它管理开发编译环境、云上虚拟机、容器镜像构建等等,Nix 官方的 NixOps 与社区的 colmena 都是基于 Nix 实现的运维工具。

为什么选择 NixOS?

好几年前就听说过 Nix 包管理器,它用 Nix 语言编写配置来管理系统依赖,此外基于 Nix 包管理器设计的 Linux 发行版 NixOS,还能随时将系统回滚到任一历史状态(额实际上这个回滚有些限制,前面提过了)。 虽然听着很牛,但是不仅要多学一门语言,装个包还得写代码,当时觉得太麻烦就没研究。

但是我最近在使用 EndeavourOS 时遇到了一系列麻烦事儿,花了大量的精力去解决,搞得我精疲力尽。我仔细一想,遇到的这些问题归根结底还是系统没有版本控制跟回滚机制,导致出了问题不能还原,就必须得各种查资料找 Bug,手动修复系统状态。

所以我就决定干脆换成 NixOS.

切换到 NixOS 后,我对它那是相当的满意,腰也不疼了,背也不酸了... 最惊艳的是,现在我可以通过仅仅一行命令(sudo nixos-rebuild switch --flake .),就能在一台全新安装的 NixOS 主机上还原我的整个 i3 桌面环境以及所有我的常用软件!

NixOS 的回滚能力与可复现能力给了我非常大的底气,我现在再也不用怕把系统搞挂了(挂了直接回滚就恢复了),于是我又在 NixOS 尝试了 Hyprland, Waybar 等等许多新鲜玩意儿~ 在以前 EndeavourOS 上我肯定是不太敢这么玩的,因为万一要是把系统玩出毛病了,就必须手动排查问题、修复系统状态,那可是相当麻烦。

随着我对 NixOS 与 Nix 的使用越来越深入,我发现它还非常适合用于同步管理多台主机的配置。目前我的个人配置 ryan4yin/nix-config 同步管理了许多主机的配置:

  • 桌面电脑
    • 一台 Macbook Pro 2020 (Intel amd64)
    • 一台 Macbook Pro 2022 (M2 aarch64)
    • 一台 NixOS 桌面 PC (amd64)
  • 服务器
    • 三台 NixOS 虚拟机(amd64)
    • 若干块 aarch64 跟 riscv64 的开发板

其中三台桌面电脑的开发环境都通过 Home Manager 管理,主要配置完全共用,在任意一台主机上修改的配置,可以通过 Git 无缝同步到其他主机上。NixOS 几乎完全帮我屏蔽了三台机器底层的 OS 与芯片架构差异,体验非常丝滑!