1. Home Manager 的定位
Home Manager 是 Nix 生态系统中管理用户级配置的利器。它填补了 NixOS 系统级配置管理的一个空白——普通用户的个人环境配置。
解决的问题:
- dotfiles 管理:
~/.bashrc、~/.vimrc、~/.config/等配置文件散落各处,换机器或重装时需要数小时重新配置 - 用户级包管理:不需要 root 权限就能安装和管理个人工具
- 跨发行版一致:无论在使用 Ubuntu、macOS、Arch 还是 NixOS,个人环境可以完全一致
- 版本控制:所有配置以代码形式存储,变更可追溯、可回滚
Home Manager 与 NixOS 的关系是互补的:NixOS 管理整个系统(系统服务、网络、硬件),Home Manager 管理用户个人环境(Shell 配置、编辑器设置、用户级包)。在 NixOS 上两者可以协同工作,在非 NixOS(如 Ubuntu 或 macOS)上 Home Manager 可以独立运行。
2. 安装方式
2.1 独立安装(任何 Linux /macOS)
# 添加 Home Manager 通道(不使用 Flakes)
nix-channel --add https://github.com/nix-community/home-manager/archive/master.tar.gz home-manager
nix-channel --update
# 安装
nix-shell '<home-manager>' -A install
2.2 作为 NixOS 模块
# /etc/nixos/configuration.nix
{ config, pkgs, ... }:
{
imports = [
<home-manager/nixos> # 导入 Home Manager NixOS 模块
];
# 在 NixOS 配置中直接定义用户配置
home-manager.users.alice = { pkgs, ... }: {
home.packages = with pkgs; [ vim git ];
programs.bash.enable = true;
};
}
2.3 作为 Flake
# flake.nix
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
home-manager = {
url = "github:nix-community/home-manager";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs = { self, nixpkgs, home-manager }:
let
system = "x86_64-linux";
pkgs = nixpkgs.legacyPackages.${system};
in
{
homeConfigurations.alice = home-manager.lib.homeManagerConfiguration {
inherit pkgs;
modules = [ ./home.nix ];
};
};
}
3. home.nix 基础结构
3.1 最小配置
# ~/.config/home-manager/home.nix
{ config, pkgs, lib, ... }:
{
# 用户信息(必填)
home.username = "alice";
home.homeDirectory = "/home/alice";
# 用户级包
home.packages = with pkgs; [
htop
jq
fzf
ripgrep
fd
tree
];
# 程序配置
programs.git = {
enable = true;
userName = "Alice";
userEmail = "alice@example.com";
extraConfig = {
init.defaultBranch = "main";
push.autoSetupRemote = true;
};
};
programs.bash = {
enable = true;
shellAliases = {
ll = "ls -la";
".." = "cd ..";
gs = "git status";
};
bashrcExtra = ''
export PATH=$HOME/.local/bin:$PATH
'';
};
# 状态版本(不要修改!)
home.stateVersion = "24.05";
}
3.2 激活配置
# Flakes 方式
home-manager switch --flake ~/.config/home-manager#alice
# 传统方式
home-manager switch
# 测试配置(不实际应用)
home-manager build
# 查看当前配置
home-manager generations
home-manager news
4. 用户级程序配置
4.1 Shell 配置
{
programs.bash = {
enable = true;
historyFileSize = 100000;
historySize = 10000;
shellAliases = {
ll = "ls -la";
".." = "cd ..";
"..." = "cd ../..";
gs = "git status";
gc = "git commit";
gp = "git push";
};
bashrcExtra = ''
# 自定义 PS1
PS1='\n\[\033[1;32m\][\u@\h]\[\033[0m\] \[\033[1;34m\]\w\[\033[0m\] \n\$ '
# 启用 fzf 补全
eval "$(fzf --bash)"
'';
};
# 或使用 Zsh
programs.zsh = {
enable = true;
enableCompletion = true;
autosuggestion.enable = true;
syntaxHighlighting.enable = true;
oh-my-zsh = {
enable = true;
theme = "robbyrussell";
plugins = [ "git" "docker" "kubectl" "fzf" ];
};
shellAliases = {
ll = "ls -la";
gs = "git status";
};
};
}
4.2 编辑器配置
{
# Vim 配置
programs.vim = {
enable = true;
plugins = with pkgs.vimPlugins; [ vim-airline nerdtree ];
settings = {
number = true;
relativenumber = true;
tabstop = 2;
shiftwidth = 2;
};
extraConfig = ''
syntax on
set hlsearch
set ignorecase
set smartcase
'';
};
# Neovim 配置(通过外部文件)
programs.neovim = {
enable = true;
defaultEditor = true;
plugins = with pkgs.vimPlugins; [
nvim-treesitter
nvim-lspconfig
telescope-nvim
];
extraConfig = builtins.readFile ./nvim/init.vim;
};
# VS Code
programs.vscode = {
enable = true;
extensions = with pkgs.vscode-extensions; [
bbenoist.nix
ms-python.python
rust-lang.rust-analyzer
];
userSettings = {
"editor.fontSize" = 14;
"editor.tabSize" = 2;
"editor.wordWrap" = "on";
};
};
}
4.3 Git 配置
{
programs.git = {
enable = true;
package = pkgs.gitAndTools.gitFull;
userName = "Alice";
userEmail = "alice@example.com";
extraConfig = {
core.editor = "vim";
init.defaultBranch = "main";
push.autoSetupRemote = true;
pull.rebase = true;
# 颜色
color.ui = true;
# 别名
alias.st = "status";
alias.co = "checkout";
alias.br = "branch";
alias.ci = "commit";
alias.lg = "log --oneline --graph --decorate";
};
# 忽略文件模板
ignores = [
"*.swp"
"*.swo"
".DS_Store"
"node_modules/"
".env"
];
# delta:增强型 diff 查看器,提供更美观的差异输出,支持语法高亮和并排对比
delta = {
enable = true;
options = {
line-numbers = true;
side-by-side = true;
decorations = {
commit-decoration-style = "bold yellow box ul";
file-decoration-style = "none";
file-style = "bold yellow ul";
};
};
};
};
}
4.4 终端与工具
{
# Alacritty 终端
programs.alacritty = {
enable = true;
settings = {
window.opacity = 0.95;
font.size = 13;
font.normal.family = "Fira Code";
colors.primary.background = "#1a1b26";
colors.primary.foreground = "#c0caf5";
};
};
# tmux
programs.tmux = {
enable = true;
shortcut = "a";
baseIndex = 1;
newSession = true;
plugins = with pkgs.tmuxPlugins; [ sensible resurrect continuum ];
extraConfig = ''
set -g mouse on
set -g default-terminal "screen-256color"
'';
};
# fzf
programs.fzf = {
enable = true;
enableBashIntegration = true;
enableZshIntegration = true;
defaultOptions = [ "--height 40%" "--layout=reverse" "--border" ];
};
# direnv
programs.direnv = {
enable = true;
nix-direnv.enable = true;
};
}
5. Dotfiles 管理
Home Manager 最强大的功能之一是管理 dotfiles。它可以自动创建 ~/.config/、~/.bashrc、~/.ssh/config 等文件。
5.1 配置文件生成
{
# 直接生成配置文件内容
home.file."/.config/alacritty/alacritty.yml".text = ''
window:
opacity: 0.95
font:
size: 13
normal:
family: Fira Code
'';
# 从仓库中的文件复制
home.file."/.ssh/config".source = ./ssh/config;
home.file."/.config/git/ignore".source = ./gitignore;
# 生成脚本
home.file."/.local/bin/my-script" = {
source = ./scripts/my-script;
executable = true;
};
# 目录复制
home.file."/.config/nvim" = {
source = ./nvim;
recursive = true;
};
}
5.2 条件配置
{ config, pkgs, lib, ... }:
with lib;
{
# 根据主机名加载不同配置
home.file."/.config/machine-specific" = mkIf (config.home.username == "work") {
text = "work-specific-config";
};
# 根据平台条件配置
programs.bash.bashrcExtra = mkIf pkgs.stdenv.isDarwin ''
export BASH_SILENCE_DEPRECATION_WARNING=1
# macOS 特定配置
export PATH="/opt/homebrew/bin:$PATH"
'';
# 根据是否存在某个包来配置
programs.vim.extraConfig = mkIf config.programs.git.enable ''
" Git integration
set nobackup
set nowritebackup
'';
}
6. 与 NixOS 协同
6.1 NixOS + Home Manager 架构
系统级 (root) 用户级 (alice)
─────────────────────────────────────────
/etc/nixos/ ~/.config/home-manager/
├── configuration.nix ├── flake.nix (可选)
├── hardware-*.nix └── home.nix
└── flake.nix
NixOS 管理: Home Manager 管理:
- 内核、驱动 - Shell 配置
- 系统服务 - 用户包
- 网络配置 - dotfiles
- 系统级包 - 编辑器配置
- 防火墙 - Git 配置
6.2 NixOS 中使用 Home Manager 模块
# /etc/nixos/configuration.nix
{ config, pkgs, ... }:
{
imports = [
<home-manager/nixos>
];
# 系统级配置
networking.hostName = "my-laptop";
boot.loader.systemd-boot.enable = true;
# 用户配置(由 Home Manager 管理)
home-manager.users.alice = { pkgs, ... }: {
home.packages = with pkgs; [
firefox
vscode
slack
];
programs.git = {
enable = true;
userName = "Alice";
userEmail = "alice@example.com";
};
programs.bash = {
enable = true;
shellAliases = {
ll = "ls -la";
};
};
home.stateVersion = "24.05";
};
# 自动激活 home-manager 配置
home-manager.useGlobalPkgs = true;
home-manager.useUserPackages = true;
}
6.3 分离配置的好处
| 场景 | 配置位置 | 工具 |
|---|---|---|
| 系统级服务 | /etc/nixos/configuration.nix | NixOS |
| 用户个人偏好 | ~/.config/home-manager/home.nix | Home Manager |
| 共享团队配置 | 导入的模块 | 两者 |
分离的好处:
- 普通用户可以修改自己的配置而无需 sudo
- 用户可以在不同机器上共享相同的 home.nix
- 重装系统时,home 配置独立备份和恢复
7. 多主机配置复用
7.1 使用 Flakes 管理多主机
# flake.nix
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
home-manager = {
url = "github:nix-community/home-manager";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs = { self, nixpkgs, home-manager }:
let
mkHome = { username, system, extraModules ? [] }:
home-manager.lib.homeManagerConfiguration {
pkgs = nixpkgs.legacyPackages.${system};
modules = [
./home-common.nix # 通用配置
./hosts/${username}.nix # 主机特定配置
] ++ extraModules;
extraSpecialArgs = { inherit username; };
};
in
{
homeConfigurations = {
"alice@laptop" = mkHome {
username = "alice";
system = "x86_64-linux";
extraModules = [ ./profiles/development.nix ];
};
"alice@desktop" = mkHome {
username = "alice";
system = "x86_64-linux";
extraModules = [ ./profiles/gaming.nix ./profiles/development.nix ];
};
"alice@macbook" = mkHome {
username = "alice";
system = "aarch64-darwin";
extraModules = [ ./profiles/development.nix ];
};
};
};
}
7.2 激活不同主机配置
# 笔记本电脑
home-manager switch --flake ~/.config/home-manager#alice@laptop
# 台式机
home-manager switch --flake ~/.config/home-manager#alice@desktop
# MacBook
home-manager switch --flake ~/.config/home-manager#alice@macbook
8. 总结
Home Manager 将 Nix 的声明式配置优势延伸到了用户级环境:
| 能力 | Home Manager 方案 | 传统方案 |
|---|---|---|
| dotfiles 管理 | home.file 声明式生成 | 手动复制、stow、chezmoi |
| 用户包 | home.packages | brew、apt、手动安装 |
| 编辑器配置 | programs.vim、programs.vscode | 手动编辑配置文件 |
| 配置版本控制 | Git 管理 home.nix | Git 管理 dotfiles 仓库 |
| 跨平台一致性 | 一份配置多处使用 | 每个平台单独维护 |
| 可复现性 | 完全可复现 | 依赖手动步骤 |
对于已经在使用 Nix 的开发者,Home Manager 几乎是必选项。它不仅解决了 dotfiles 管理的长期痛点,还提供了一种优雅的方式来在多台机器之间同步开发环境——只需复制 flake.nix 和 home.nix,几秒钟后即可获得完全一致的开发体验。
Home Manager 的常见陷阱
PATH 污染:未正确隔离的 Home Manager 环境可能导致系统工具被用户包覆盖:
# 问题:用户的 git 优先于系统 git
$ which git
/home/user/.nix-profile/bin/git # 可能版本与团队不一致
# 解决:使用 `home.sessionPath` 控制顺序
# 或明确指定 `programs.git.package` 版本
与系统包管理器冲突:同时使用 Home Manager 和 Homebrew 可能导致同一工具存在两个版本。建议:
- macOS:完全切换到 Home Manager,移除 Homebrew
- Linux:保留系统包管理器用于 GUI 应用,开发工具全部走 Home Manager
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。