使用 Nix 管理及同步 dotfiles

使用 Nix 管理及同步 dotfiles

迁移背景

我的开发平台是 macOS,以及家里 PVE 上开启的虚拟机,加上一个定期更换机器的 vps,平台只有 Linux 和 macOS,但是机器多,每次远程到 linux 上的时候,那只能用原生 vim,跟 macOS 上我配置的功能相去甚远,所以想着能不能使用 git 同步我的配置。

初始方案: shell 脚本直接操作

其实备份的 dotfiles 无非就是一些 shell、cli 工具配置,所以自然想到了使用 shelll 去管理这些 dotfiles,我的 shell 编程经验比较少,也不那么太喜欢 shell,所以我面临了几个问题:

  1. shell 经验不足,即使使用 gpt,写出来的东西也挺丑陋
  2. shell 有局限性,比如没法自动升级之类的,想要实现,受制于 1

总结来说,就是 shell 编程不熟悉,无法完成非常高深的同步需求,如果真按照需求写出来了,成本非常高。 所以一直以来,都是把 dotfile 作为存储仓库来使用,自动化的部分不多,有需要了拉下来然后手动执行命令配置。

Nix 拯救了我

前段时间在推上看到了这个Nix Darwin Kickstarter (opens in a new tab)仓库,了解到了 Nix,内心直呼这不就是我想要的么,于是开启了迁移踩坑之旅。

什么是 Nix?

还是上面 Kickstarter 仓库的作者,写了一本小册子 (opens in a new tab),用来帮助初学者入门,简单总结下,有兴趣可以看原链接

  1. Nix 是包管理器,使用 Nix 语言即可使用 Nix 包管理器
  2. Nix 语言是一门函数式语言
  3. NixOS 是使用 Nix 包管理器管理整个系统的发行版,可以管理任何的系统设置
  4. home-manager 是用来管里用户层级软件包的软件
  5. nix-darwin 可以用来管理 macOS 上的 brew 以及系统配置

简而言之,使用 nix 可以使用编程的方式定义自己系统里所需要的所有软件。 我没有使用 NixOS,我平时不会使用 Linux 的 GUI 界面,都是 ssh 过去,没必要徒增难度去强行使用 NixOS,所以我的 dotfils 没有关于这部分的内容

我的 dotfiles

我的 dotfiles 项目 (opens in a new tab)结构如下

  • flake.nix: 项目入口,描述了基本的定义
  • home-manager/: home-manager 配置,描述了被 home-manager 所管理的一切软件和配置
  • lib/: Nix 工具函数
  • machines/: 每个机器的不同配置.
  • overlays/: overlay 文件夹,暂时只有 rust.
  • config/: 第三方软件配置文件夹.

上面出现了一个 overlay 和 home-manager

  1. overlay 是用来安装自定义软件的一个方式
  2. hm 是用来管理用户层级的软件以及配置的一个工具,我基本上所有的软件都在这里定义

如何安装软件和取舍配置

首先安装的软件分为三部分

  1. cli 软件,这部分软件几乎可以完全被 hm 管理
  2. macOS 上的 GUI 软件,比如 chrome,这些软件通过 brew 管理
  3. nvm 或者类 nvm 的动态版本管理软件,作为前端,nvm 必不可少,但是 nix 作为函数式管理的思路,又不适合 nvm,所以需要一些灵活性的 hack

第三方软件配置方面,实际上 hm 冗长的文档绝大部分都是配置各种软件的字段,但我不是非常想用

  1. 软件版本更新之后 hm 可能更新不及时
  2. 生成的配置无法随意更改,要想更改只能更改代码,会比较麻烦

所以最终的方案是

  • 只使用 nix 安装软件
  • 配置使用每个软件的官方配置方式,放到 config/文件夹里,通过脚本批量创建软连接

最终安装的软件

  • 使用 nix-darwin 管理 brew,安装了 39 个 GUI 软件
  • 使用 hm 管理将近五十个 cli 软件
  • 使用 shell 管理 config 文件夹

最终包括我的 mac,一共 6 台机器都使用一样的命令行配置,效率提升

感想

Nix 是一个非常强大的工具,最近几年热度也持续攀升,但总的来说有以下缺点

  1. 非常难写,在我看来和 rust 已经基本一个难度层级,而且网上资料驳杂,从这个角度来说比 rust 还难。
  2. 报错不清晰,需要是不是在源代码里找线索
  3. 需要更多的 shell 知识,由于主要配置的是 cli,shell 新手想要使用 nix,那么可能是地狱级难度

最重要的优点就是一次使用,终身受益。一旦确定了基本架构并且完成项目,那么剩下的时间就是小修补,非常省时省力,不容易出问题。

总的来说还是非常推荐使用 Nix 作为 dotfiles 的管理工具,多花点时间,code like a pro!