nix and home-manager, 最好的系统环境管理工具
前言
由 chatgpt 生成…
在当今的技术领域,配置管理变得越来越重要。对于开发者和技术爱好者来说,保持一致的开发环境和工具配置是至关重要的。然而,传统的配置文件管理方式可能会导致配置分散、混乱和难以维护的问题。
幸运的是,有一个强大的工具可以帮助我们解决这些问题,那就是home-manager。Home-manager是一个基于Nix的工具,旨在帮助用户统一管理他们的配置文件,并通过声明性的方式进行配置。
本文将介绍如何安装home-manager以及使用它来管理一些常见的配置文件,例如zsh、bash和vim。我们将探索如何使用home-manager的内置功能和插件来简化配置文件的管理,并介绍如何定制和贡献新的配置。
接下来的内容中, 主要围绕两个工具的使用.
home-manager
声明式, 函数式, 面向终态的用户配置管理方案- 通过
yadm
完成将配置文件同步到 github
安装 home-manager
传统 nix installer
假设当前系统处于初始化状态, 这里首先更新 channel , 接着安装最新的 home-manager.
官方安装教程 https://nix-community.github.io/home-manager/index.html#sec-install-standalone
可选的方式还有通过 flake 加载.
1 | nix-channel --add https://github.com/nix-community/home-manager/archive/master.tar.gz home-manager |
安装完毕, home-manager 会自动生成一个最小化配置在 ~/.config/home-manager/home.nix
这个文件中. 这里 home-manager 的可以告一段落
官方文档中会提及修改
.profile
等操作. 这部分会在program
段落中进行.
通过 flake - standalone 安装
通过 flake 安装 home-manager 需要对 flake 有一定了解, 否则安装过程会比较曲折.
我个人强烈建议通过传统方式了解 home-manager 如何使用,再迁移到 flake. 虽然流程长了点, 但可以减少被 flake 折磨的风险.
通过 flake 方式引入 home-manager , 就需要注意 system 参数, 按照自己的需求, 配置好
1 | { |
flake.nix 会引入 home.nix , 也就是传统方式下用的 home.nix, 一份配置也可以做到支持多种方式使用.
注意, users 和 systems 需要根据实际需求改成自己的值, 我手里有不少机器共用着一份配置, 只要把需要的 system 和 user 写上就行了.
还有一些更加复杂的情况, 比如自定义 home 路径等, 这里就不展开了.
测试的构建命令 USER=user1 nix run 'home-manager' -- --flake . build
如果构建成功, 可以在 result 目录下看到生成的 home 配置
最终通过 nix run 'home-manager' -- --flake . switch
完整例子请参考 https://github.com/hitsmaxft/mixed-darwin-homemanager-example
通过 yadm 将配置文件同步到 github
在通过 nix-shell 载入 yadm 和相关软件, 通过执行 nix-shell -p pkg1 pkg2
, 可以快速得到临时环境
假设我们的 dotfiles 将上传到
$GIT_USER
这个用户名下的dotfiles
仓库.
那么 github 全路径为[email protected]:${GIT_USER}/dotfiles.git
1 | yadm init |
如果仓库中没有任何内容, 这是应该直接推送到 master
分支, (或者 main )
1 | yadm push -u origin master |
假设你已经有现成的 dotfiles, 可以直接执行
yadm clone [email protected]:${GIT_USER}/dotfiles.git
一步初始化
home.program: 声明式管理shell 环境
home-manager 可以用于替代 stow
和 homebrew
, 通过在 ~/.nix-profile/bin
下加入软链等, 方便地管理当前环境中的各种工具.
对于经常需要修改开发环境的开发者
home.programs
内置了大量 常用 shell 命令的配置, 通过这些配置项, 一方面自动化往当前 home.nix 中增加 nix
package, 同时还能生成对应的配置文件, 替代手动管理配置文件.
解决了配置文件分散在各个目录和文件下的脏乱差现场, 现在配置文件都托管给了 nix 通过 home-manager
进行集中化管理, 同时
社区中大量已经贡献进来的 programs 配置项不仅可以直接使用, 后面会介绍如何通过 import
定制已有的 program
.
当然可以也新增自己的 program 实现, 最后贡献给
home-manager
社区.
接下来章节中, 首先介绍一些常见场景下的 home-manager
使用案例
- zsh
- bash
- vim
热身开始, 通过 nix 管理 zsh 配置文件
过去配置 zsh, 一般是通过修改 .zshrc
.zprofile
和 .zshenv
这些文件, 如果需要同步到不同机器, 可以借助 yadm
同步到 github
.
随着 shell 的配置项的代码量不断膨胀,
接下来将介绍如何通过 home-manager
的 programs.zsh
配置项, 声明式管理 zsh 的所有配置文件.
以下是一个 zsh
的配置实例, 内置了一部分常用的 zsh
特性.
- 内置
oh-my-zsh
, 启用vi-mode
和jump
插件 .zshenv
加入 nix 环境变量 (这就是前面安装 nix 环境中跳过的部分)envExtra
.zshrc
加入自定义选项initExtraFirst
这部分脚本会在 .zshrc 最前面, 先于oh-my-zsh
和其他脚本initExtra
这部分脚本优先级低于其他的initExtraBeforeCompInit
这部分脚本将在 zsh插件 加载之前执行
具体实现见 https://github.com/nix-community/home-manager/blob/master/modules/programs/zsh.nix
zshrc 配置项大致的优先级为 initExtraFirst > initExtraBeforeCompInit > plugsin > ohmyzsh > initExtra
1 | {pkg, ...} : |
管理 bash 配置
接下来是一个 bash
的配置实例.
给 bash 内置了补全
功能和 starship
(类似 p10k 的 zsh 提示符主题, rust 实现, 需要预先在 packages 中安装)
home-manager 中内置了 starship , 可以通过 programs.starship 快速配置. 这里只是提供一个实例
1 | { |
在 .bashrc
中, 可以看到最终效果为:
1 | if [[ ! -v BASH_COMPLETION_VERSINFO ]]; then |
通过 import
管理自定义 program
这里提供一个我自己的例子. aigc
是一个自定的 program , 会自动根据配置, 选择不同的 llm-cli 命令,生成对应的git-ai-commit
指令.
options.programs.ai-commit
定义了配置的选项config
则是根据选项, 修改了 home.packages 实现动态添加命令
1 | ## modules/aigc.nix |
将 aigc.nix 放在了 modules
配置目录下.
并且通过配置启用
1 | home.imports = [ ./modules/aigc.nix ]; |
其实除了自定义 program, 还有一种用法增强现有的 programs, 通过 module 实现模块化管理
这里举一个给 sd 增加一个 settings 的自定义选项.
1 | #~/.config/home-manager/modules/xx.nix |
接下来需要在 home.nix 中通过 import
导入 xxx
1 | # home.nix |
通过 overlay 增加自定义函数和应用包
这里举一个例子, 往 <nixpkgs>
中新增 vim-darwin
包.
- 关闭 GUI
- 开启 darwin 特性, vim 和 mac 剪贴板交互需要开启该编译选项
- 内置两个基础插件
1 | # ~/.config/home-manager/overlays/default.nix |
完成上面的基础 overlays
脚本, 接下来需要在 home-manager 中引用.
1 | # ~/.config/home-manager/home.nix |
再次运行 home-manager switch
完成 overlays
加载
最后, 再次修改 home.nix
的 home.pacakges
完成 vim-darwin
的安装
1 |
|
总结
就此, 本文总结了大部分常见的 home-manager 配置管理技巧, 更多内容可以参考官方文档 https://nix-community.github.io/home-manager/index.html
相对于手动管理配置文件, 采用 home-manager 有以下几个优点
- 声明式配置 - 使用 home-manager,可以使用 Nix 表达式以声明性的方式定义配置。这样可以实现版本控制、可复现性和易分享的配置。
- 集中化管理 - home-manager 提供了一种集中管理您的 shell 环境配置的方法,而不是将配置文件分散在不同的目录和文件中。这样可以更容易地维护和更新配置。
- 模块化, 可复用 - home-manager 以模块化的方式处理配置,允许您根据需要启用或禁用特定的组件或程序。它还提供了许多预配置的程序,可以直接使用或根据需求进行自定义。
- 支持版本管理 - 由于 home-manager 的配置存储在像 Git 这样的版本控制系统中,您可以轻松跟踪更改、还原到以前的版本,并与他人合作。这在管理 shell 配置时提供了额外的安全性和灵活性