Bootstrap
One Flake to Rule Them All – for macOS (nix-darwin), NixOS, and home-manager.
克隆仓库,运行一条命令,看着你的系统按你的意愿配置好。不再有配置混乱,有更多时间做重要的事——比如看着终端自动配置时品一杯咖啡。
✨ git clone 你的理智之路
⚡ nix run 你的荣耀之路
特性
- 零启动脚本 — 纯
nix命令,无需额外脚本 - 多主机、多用户 — 所有机器配置集中在一个仓库
- 确定性 — lock 文件锁定每一个比特
- 模块化 — 自由组合 common 模块(
git、zsh、tmux…) - 项目模板 —
nix flake init -t脚手架,支持 Deno、Java、Rust+WASM - 独立 Home Manager — 不依赖 nix-darwin,通过
home-manager switch --flake使用
支持平台
| 平台 | 架构 | 状态 |
|---|---|---|
| macOS (nix-darwin) | aarch64-darwin, x86_64-darwin | ✅ 可用 |
| NixOS | x86_64-linux, aarch64-linux | 🚧 开发中 |
| Standalone Home Manager | 所有平台 | ✅ 可用 |
快速链接
安装 Nix
Bootstrap 基于 Nix 包管理器,首先需要安装 Nix。
官方安装脚本
sh <(curl -L https://nixos.org/nix/install) --daemon
安装完成后,重启终端或运行:
. /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh
验证安装
nix --version
启用 Flakes
Bootstrap 使用 Flakes,需要确保已启用:
mkdir -p ~/.config/nix
cat > ~/.config/nix/nix.conf << 'CONF'
experimental-features = nix-command flakes
CONF
下一步
macOS (nix-darwin) 配置
1. 克隆仓库
git clone git@github.com:BeauvnTu/Bootstrap.git
cd Bootstrap
2. 进入脚本目录
cd scripts
3. 运行构建
根据你的架构选择对应的脚本:
# Apple Silicon (M1/M2/M3)
sh ./aarch64-darwin/build-switch
# Intel Mac
sh ./x86_64-darwin/build-switch
4. 首次运行后的操作
构建完成后,系统会自动配置:
- Homebrew 包(kitty, ghostty)
- macOS 系统设置
- Home Manager 用户配置(git, zsh, tmux, 开发工具包)
- 系统字体
可用命令
| 命令 | 说明 |
|---|---|
build | 仅构建,不切换 |
build-switch | 构建并切换到新配置 |
apply | 应用配置 |
rollback | 回滚到上一版本 |
create-keys | 创建密钥 |
copy-keys | 复制密钥 |
check-keys | 检查密钥 |
故障排查
NixOS 配置
⚠️ Linux (NixOS) 支持目前正在开发中,敬请期待后续更新。
计划中的功能
- 完整的 NixOS 系统配置
- Disko 磁盘分区自动化
- 多主机配置管理
相关输入
Axiom 的 flake.nix 已包含以下 NixOS 相关输入:
disko— 声明式磁盘分区home-manager— 用户环境管理
当前状态
NixOS hosts 配置位于 hosts/nixos.nix,但尚未完善。
目录结构
.
├── assets/ # 静态资源(图标、图片)
│ ├── linux.svg
│ ├── macos.svg
│ └── nix-icon.svg
├── docs/ # mdBook 文档站
│ ├── book.toml
│ ├── book/ # 构建输出(GitHub Pages)
│ └── src/ # Markdown 源文件
├── hosts/ # 主机配置
│ ├── darwin.nix # macOS 系统配置入口
│ └── nixos.nix # NixOS 配置模板(开发中)
├── inventory/ # 身份信息
│ └── default.nix
├── modules/ # 模块化配置
│ ├── common/ # 跨平台通用模块(Home Manager)
│ │ ├── default.nix
│ │ ├── git.nix
│ │ ├── packages.nix
│ │ ├── tmux.nix
│ │ └── zsh.nix
│ └── macos/ # macOS 专用模块
│ ├── default.nix
│ ├── home-manager.nix
│ ├── homebrew.nix
│ └── packages.nix
├── overlays/ # Nixpkgs overlay
│ └── README.md
├── scripts/ # 构建/部署脚本
│ ├── aarch64-darwin/
│ ├── x86_64-darwin/
│ ├── x86_64-linux/
│ ├── apply.sh
│ └── setup.sh
├── templates/ # nix flake init 项目模板
│ ├── default.nix
│ ├── deno/
│ ├── java/
│ └── rust-wasm/
├── flake.lock # Flake 依赖锁定
├── flake.nix # Flake 入口
├── home.nix # 独立 Home Manager 配置入口
└── README.md
Flake 设计
flake.nix 是仓库的核心入口,定义了所有输入、输出和系统配置。
输入 (Inputs)
| 输入 | 用途 |
|---|---|
nixpkgs | Nix 包集合 (nixos-unstable) |
home-manager | 用户环境管理 |
darwin | nix-darwin (macOS 系统配置) |
nix-homebrew | Nix 管理 Homebrew |
homebrew-bundle/core/cask | Homebrew 相关 |
disko | 声明式磁盘分区 (NixOS) |
fenix | Rust 工具链 |
输出 (Outputs)
Apps
每个平台都有一组便捷的构建命令:
Linux Apps:
applybuild-switchcopy-keyscreate-keyscheck-keysinstall
Darwin Apps:
applybuildbuild-switchcopy-keyscreate-keyscheck-keysrollback
Darwin Configurations
macOS 系统配置由 hosts/darwin.nix 导入,支持 aarch64-darwin 和 x86_64-darwin。
Home Configurations
独立的 Home Manager 配置,不依赖 nix-darwin:
homeConfigurations = {
${inventory.identity.user} = home-manager.lib.homeManagerConfiguration {
pkgs = nixpkgs.legacyPackages.aarch64-darwin;
extraSpecialArgs = {
inherit inputs;
axiomIdentity = inventory.identity;
};
modules = [ ./home.nix ];
};
};
使用方式:
home-manager switch --flake .#moonshot
DevShells
为所有支持的平台提供统一的文档开发环境:
devShells = forAllSystems (system: {
default = docsShell system;
});
支持的平台:
x86_64-linuxaarch64-linuxaarch64-darwinx86_64-darwin
当前唯一的 devShell 是 default,包含 mdbook 用于构建文档。
Templates
项目模板通过 templates/default.nix 引入:
templates = import ./templates;
可用模板:
deno— Deno 运行时java— JDK 17 + Maven + Gradlerust-wasm— Rust + WebAssembly
使用方式:
nix flake init -t github:BeauvnTu/Bootstrap#<template-name>
Hosts
Hosts 目录定义了不同机器的系统配置。
darwin.nix
macOS 主机配置入口,导入 darwin 输入并定义系统配置。
主要配置:
- 用户配置 — 创建系统用户,设置 shell 为 zsh
- Nix 配置 — substituters、trusted keys、自动 GC
- 系统设置 — 状态版本、NSGlobalDomain 默认行为
- 系统字体 — Hack、Meslo Nerd Font、Noto、Roboto Mono Nerd Font 等
支持 aarch64-darwin 和 x86_64-darwin 两个架构。
nixos.nix
NixOS 主机配置模板(开发中),目前仅包含注释掉的示例配置。
home.nix
独立的 Home Manager 配置入口,不依赖 nix-darwin。
用于:
- 在非 NixOS Linux 上使用 Home Manager
- 在 macOS 上仅管理用户环境而不管理系统
{ axiomIdentity, pkgs, inputs, ... }:
{
imports = [ ./modules/common ];
home = {
username = axiomIdentity.user;
homeDirectory = if pkgs.stdenv.isDarwin then
"/Users/${axiomIdentity.user}"
else
"/home/${axiomIdentity.user}";
};
programs.home-manager.enable = true;
}
多主机管理
设计目标是支持多主机、多用户。所有机器配置集中在一个仓库,通过不同的 host 文件区分。
Common 模块
Common 模块是跨平台共享的配置,被 macOS(通过 modules/macos/home-manager.nix)和独立 Home Manager(通过 home.nix)共同导入。
包含模块
包管理
modules/common/packages.nix 定义了所有用户级安装的包,包括:
- Go 开发 — go, gopls, delve, go-tools, gotestsum
- Rust 开发 — 通过 fenix 提供的完整工具链(含 rust-src)
- JavaScript 开发 — nodejs_22, pnpm
- Python — uv, python3
- Lua — lua, luarocks
- 基础开发工具 — git, tmux, neovim, ripgrep, fd, fzf, lazygit, helix 等
- 系统工具 — bat, tree, coreutils, zip, unzip
身份数据
inventory/default.nix 定义了系统的基本身份信息,并通过 specialArgs / extraSpecialArgs 传给系统模块和 Home Manager 模块:
identity = {
user = "moonshot";
gitName = "Tetsuya";
gitEmail = "1376490336@qq.com";
};
Git
modules/common/git.nix 定义了 Git 版本控制工具的配置。
基础配置
| 选项 | 值 | 说明 |
|---|---|---|
userName | axiomIdentity.gitName | 从身份模块读取 |
userEmail | axiomIdentity.gitEmail | 从身份模块读取 |
init.defaultBranch | main | 默认分支名 |
core.editor | vim | 默认编辑器 |
core.autocrlf | input | 行尾符处理 |
pull.rebase | true | pull 时使用 rebase |
rebase.autoStash | true | rebase 前自动 stash |
启用功能
- Git LFS — 大文件支持
- 全局忽略 —
*.swp文件
Tmux
modules/common/tmux.nix 配置了功能丰富的 Tmux 终端复用器。
前缀键
| 键位 | 功能 |
|---|---|
C-x | 前缀键(替代默认的 C-b) |
分屏操作
| 快捷键 | 功能 |
|---|---|
prefix + x | 水平分屏 |
prefix + v | 垂直分屏 |
Alt + h/j/k/l | 在 pane 间移动 |
Ctrl + h/j/k/l | 智能切换(兼容 Vim) |
插件
| 插件 | 功能 |
|---|---|
vim-tmux-navigator | 与 Vim 无缝导航 |
sensible | 合理默认配置 |
yank | 系统剪贴板集成 |
prefix-highlight | 前缀键状态高亮 |
power-theme | 金色主题 gold |
resurrect | 会话保存/恢复 |
continuum | 自动保存(每 5 分钟) |
其他配置
- 鼠标支持:启用
- 历史限制:50000 行
- 焦点事件:启用(减少 Vim 延迟)
- 转义时间:10ms
Vim
⚠️ 当前配置使用 Neovim(
pkgs.neovim)作为编辑器,通过modules/common/packages.nix安装。Vim 模块文档保留作为历史参考。如果你需要自定义 Neovim 配置,建议:
- 在
modules/common/下创建neovim.nix- 在
modules/common/default.nix中导入- 或使用独立的 Neovim 配置仓库(如 nvim-lua/kickstart.nvim)
当前状态
仓库中没有 modules/common/vim/ 目录。modules/common/default.nix 仅导入:
git.nixzsh.nixtmux.nix
Neovim 作为普通包通过 modules/common/packages.nix 安装,不附带额外的 Nix 配置。
Zsh
modules/common/zsh.nix 配置了 Zsh Shell 环境。
Oh My Zsh
| 配置 | 值 |
|---|---|
| 主题 | robbyrussell |
| 插件 | git, web-search |
环境变量
# PATH 追加
/opt/homebrew/bin # macOS Homebrew
$HOME/.local/bin
$HOME/.pnpm-packages/bin
$HOME/.npm-packages/bin
$HOME/.local/share/bin
$HOME/.cargo/bin # Rust/Cargo
# NPM
NPM_CONFIG_PREFIX=$HOME/.npm-packages
别名
| 别名 | 命令 |
|---|---|
diff | difft (语法感知的 diff) |
ls | ls -G |
ll | ls -la |
la | ls -a |
函数
| 函数 | 说明 |
|---|---|
shell <pkg> | 快速进入 nix-shell,如 shell go |
Nix 集成
自动检测并加载 Nix daemon 环境:
/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh/nix/var/nix/profiles/default/etc/profile.d/nix.sh
本地覆盖
支持本地自定义配置:
$HOME/.zshenv.local— 环境变量覆盖$HOME/.zshrc.local— 交互式配置覆盖
历史记录
- 大小:50000 条
- 排除常用命令:
pwd,ls,cd - 去重:启用
macOS 模块
modules/macos/ 目录包含 macOS 专用的配置模块。
模块结构
# modules/macos/default.nix
{ pkgs, ... }:
{
imports = [
./home-manager.nix # Home Manager 配置
./homebrew.nix # Homebrew 包管理
];
environment.systemPackages = with pkgs; [ zsh ];
}
注意:modules/macos/packages.nix 存在但未被 default.nix 导入。其中的包定义已通过其他方式整合到配置中。
子模块
Home Manager
modules/macos/home-manager.nix 配置 Home Manager 用户环境。
配置
| 选项 | 值 | 说明 |
|---|---|---|
useGlobalPkgs | true | 使用全局 nixpkgs |
backupFileExtension | "backup" | 备份后缀 |
导入的 Common 模块
Home Manager 用户配置导入了所有 common 模块:
users.${identity.user} = { ... }: {
imports = [
../common
];
};
../common 包含:
git.nix— Git 配置zsh.nix— Zsh 配置tmux.nix— Tmux 配置
参数传递
Home Manager 通过 extraSpecialArgs 接收外部参数:
home-manager.extraSpecialArgs = {
inherit axiomIdentity inputs;
};
axiomIdentity— 用户身份信息(来自inventory/default.nix)inputs— Flake 的所有输入(用于fenixRust 工具链等)
其他设置
enableNixpkgsReleaseCheck = false— 禁用版本检查(在modules/common/default.nix)stateVersion = "23.11"— Home Manager 版本(在modules/common/default.nix)manual.manpages.enable = false— 禁用 man page(在modules/common/default.nix)
Homebrew
modules/macos/homebrew.nix 配置 Homebrew 包管理器。
当前配置
homebrew = {
enable = true;
brews = []; # 空列表
casks = [
"kitty"
"ghostty"
];
};
大部分包通过 Nix/Home Manager 管理,Homebrew 保留用于 GUI 应用。
通过 Nix 管理 Homebrew
使用 nix-homebrew 输入来通过 Nix 声明式管理 Homebrew,确保 Homebrew 本身也是可复现的。
在 hosts/darwin.nix 中配置:
nix-homebrew = {
user = axiomIdentity.user;
enable = true;
mutableTaps = false;
autoMigrate = true;
taps = {
"homebrew/homebrew-core" = homebrew-core;
"homebrew/homebrew-cask" = homebrew-cask;
"homebrew/homebrew-bundle" = homebrew-bundle;
};
};
Packages
包定义分散在两个文件中:
modules/common/packages.nix— 用户级包(通过 Home Manager 安装)modules/macos/packages.nix— 遗留文件(当前未被导入)
用户级包 (modules/common/packages.nix)
Go 开发
| 包 | 说明 |
|---|---|
go | Go 编译器 |
gotags | ctags for Go |
gopls | Go LSP |
delve | Go 调试器 |
go-tools | Go 工具集 |
gotestsum | 测试输出美化 |
Rust 开发
通过 fenix 提供完整工具链:
| 组件 | 说明 |
|---|---|
cargo | 包管理器 |
clippy | Linter |
rustc | 编译器 |
rustfmt | 格式化 |
rust-src | 标准库源码(rust-analyzer 需要) |
rust-analyzer | LSP |
使用 USTC 镜像加速下载:
fenixPkgs.toolchainOf {
channel = "stable";
date = "2025-09-18";
sha256 = "sha256-SJwZ8g0zF2WrKDVmHrVG3pD2RGoQeo24MEXnNx5FyuI=";
root = "https://mirrors.ustc.edu.cn/rust-static/dist";
}
JavaScript 开发
| 包 | 说明 |
|---|---|
nodejs_22 | Node.js |
pnpm | 包管理器 |
Python
| 包 | 说明 |
|---|---|
uv | 极速 Python 包管理器 |
python3 | Python 解释器 |
Lua
| 包 | 说明 |
|---|---|
lua | Lua 解释器 |
luarocks | Lua 包管理器 |
基础开发工具
| 包 | 说明 |
|---|---|
git, git-lfs, tig | 版本控制 |
ripgrep, fd, fzf | 搜索工具 |
universal-ctags | 代码标签 |
neovim | 编辑器 |
gcc, gnumake | 编译工具 |
lazygit | TUI Git |
chezmoi | 点文件管理 |
helix | 模态编辑器 |
dockerfile-language-server-nodejs | Dockerfile LSP |
系统工具
| 包 | 说明 |
|---|---|
bat | 增强 cat |
tree | 目录树 |
coreutils | GNU 核心工具 |
zip, unzip | 压缩工具 |
系统级字体 (hosts/darwin.nix)
在 hosts/darwin.nix 中配置的系统级字体:
| 包 | 说明 |
|---|---|
hack-font | Hack 字体 |
meslo-lgs-nf | Meslo Nerd Font |
noto-fonts | Noto 字体 |
noto-fonts-emoji | Emoji 字体 |
nerd-fonts.roboto-mono | Roboto Mono Nerd Font |
powerline | Powerline 字体 |
Templates 概览
Bootstrap 提供了一系列 nix flake init 模板,用于快速初始化各语言的开发环境。
什么是 Template
Nix Template 是一种**项目脚手架(scaffolding)**机制,用于快速生成带有 Nix 开发环境配置的新项目。
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ bootstrap 仓库 │ │ nix flake init │ │ 新项目目录 │
│ (远程存储) │ │ │ │ │
│ templates/ │────→│ 复制模板文件 │────→│ flake.nix │
│ └── deno/ │ │ 到本地新项目 │ │ (独立自包含) │
│ └── flake.nix│ │ │ │ │
└─────────────────┘ └─────────────────┘ └─────────────────┘
核心特点:
- 生成后的项目是独立的,不依赖 bootstrap 仓库
- 新项目有自己的
flake.lock,版本自主可控 - 可以提交到新项目的 git,团队共享
使用方式
远程使用
nix flake init -t github:BeauvnTu/Bootstrap#<template-name>
本地使用(开发测试)
mkdir ~/projects/my-app && cd ~/projects/my-app
nix flake init -t ~/github/self/bootstrap#<template-name>
nix develop
路径根据本地 bootstrap 仓库实际位置调整。
可用模板
| 模板 | 说明 | 使用 |
|---|---|---|
| Deno | Deno 运行时 | nix flake init -t github:BeauvnTu/Bootstrap#deno |
| Java | JDK 17 + Maven + Gradle | nix flake init -t github:BeauvnTu/Bootstrap#java |
| Rust + WASM | Rust + WebAssembly | nix flake init -t github:BeauvnTu/Bootstrap#rust-wasm |
通用特性
所有模板都支持以下平台:
aarch64-darwin(Apple Silicon)x86_64-darwin(Intel Mac)aarch64-linuxx86_64-linux
模板生成后的项目结构
以 Deno 模板为例,执行 nix flake init 后:
my-app/
├── flake.nix # 从模板复制的项目级 flake
├── flake.lock # 自动生成的版本锁定文件
└── ... # 你的项目代码
生成的 flake.nix 是完全独立的 project 级别 flake,与 bootstrap 再无耦合。
flake.nix 示例
以 Deno 模板为例,生成的 flake.nix 内容类似:
{
description = "Deno project template";
inputs.nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
outputs = { self, nixpkgs }:
let
forAllSystems = nixpkgs.lib.genAttrs [
"aarch64-darwin" "x86_64-darwin"
"aarch64-linux" "x86_64-linux"
];
in
{
devShells = forAllSystems (system:
let pkgs = nixpkgs.legacyPackages.${system}; in
{
default = pkgs.mkShell {
buildInputs = with pkgs; [ deno ];
};
});
};
}
初始化完成后即可开始开发:
# 进入开发环境
nix develop
# 各语言示例
go mod init my-api # Go
npm init # Node.js
cargo init # Rust
定义位置
模板在 flake.nix 中通过 templates/default.nix 引入:
templates = import ./templates;
templates/default.nix 内容示例:
{
templates = {
deno = {
path = ./deno;
description = "Deno project";
};
# ...
};
}
自定义模板
如需添加新模板:
- 在
templates/下创建新目录(如templates/my-template/) - 编写
flake.nix(project 级别) - 在
templates/default.nix中注册
# templates/default.nix
{
templates = {
# ... 已有模板
my-template = {
path = ./my-template;
description = "My custom project template";
};
};
}
常见问题
模板初始化后想更新依赖版本?
nix flake update
如何查看模板内容而不初始化?
ls ~/github/self/bootstrap/templates/deno/
cat ~/github/self/bootstrap/templates/deno/flake.nix
可以修改生成后的 flake.nix 吗?
完全可以。nix flake init 只是复制模板,生成后的文件完全由你控制。
团队成员没有 Nix 怎么办?
只需:
- 安装 Nix(https://nixos.org/download)
- 进入项目目录执行
nix develop
相关命令速查
| 命令 | 说明 |
|---|---|
nix flake init -t <source>#<name> | 从模板初始化项目 |
nix develop | 进入当前项目的开发环境 |
nix flake update | 更新 flake.lock 依赖 |
nix flake show | 查看当前 flake 的输出 |
nix flake metadata | 查看 flake 元信息 |
Deno
Deno 运行时开发环境模板。
使用
nix flake init -t github:BeauvnTu/Bootstrap#deno
包含
| 包 | 说明 |
|---|---|
deno | Deno 运行时 |
文件
templates/deno/flake.nix
Java
Java 开发环境模板,基于 JDK 17,附带 Maven 和 Gradle 构建工具。
使用
nix flake init -t github:BeauvnTu/Bootstrap#java
包含工具
| 包 | 说明 |
|---|---|
jdk17 | Java 17 JDK |
maven | Maven 构建工具 |
gradle | Gradle 构建工具 |
初始化后
# 进入开发环境
nix develop
# 验证版本
java -version
mvn -version
gradle -version
Rust + WebAssembly
Rust WebAssembly 开发环境模板。
使用
nix flake init -t github:BeauvnTu/Bootstrap#rust-wasm
包含
| 包 | 说明 |
|---|---|
stable.toolchain | Rust 稳定版工具链 |
wasm32-unknown-unknown | WASM 目标 |
wasm-pack | WASM 打包工具 |
binaryen | WASM 优化工具 |
wabt | WASM 二进制工具 |
lld | LLVM 链接器 |
git | 版本控制 |
nodejs_20 | Node.js |
rust-analyzer | Rust LSP |
环境变量
| 变量 | 值 |
|---|---|
EDITOR | vim |
WASM_PACK_CACHE_DIR | $HOME/.wasm-pack |
CARGO_TARGET_WASM32_UNKNOWN_UNKNOWN_LINKER | lld |
脚本概览
scripts/ 目录包含各架构的构建和部署脚本。
目录结构
scripts/
├── aarch64-darwin/ # Apple Silicon Mac
│ ├── apply
│ ├── build
│ ├── build-switch
│ └── rollback
├── x86_64-darwin/ # Intel Mac
│ ├── apply
│ ├── build
│ ├── build-switch
│ ├── check-keys
│ ├── copy-keys
│ ├── create-keys
│ └── rollback
└── x86_64-linux/ # x86_64 Linux
├── apply
└── build-switch
注意:
aarch64-linux是x86_64-linux的符号链接。
脚本说明
build-switch
构建并切换到新配置(最常用):
cd scripts
sh ./aarch64-darwin/build-switch
流程:
nix build .#darwinConfigurations.aarch64-darwin.systemsudo darwin-rebuild switch --flake .#aarch64-darwin- 清理
result链接
build
仅构建,不切换:
sh ./aarch64-darwin/build
apply
交互式配置应用脚本,支持:
- 自动检测用户名
- 从 git config 读取身份信息
- 密钥生成和管理
- 系统类型自动识别
rollback
回滚到上一系统 generation:
sh ./aarch64-darwin/rollback
create-keys / copy-keys / check-keys
密钥管理脚本(x86_64-darwin 特有):
| 脚本 | 功能 |
|---|---|
create-keys | 生成新的 SSH/年龄密钥 |
copy-keys | 复制密钥到目标位置 |
check-keys | 检查密钥状态 |
清理 Launchpad 中已移除的 Nix 应用
问题描述
在 configuration.nix 或 home-manager 配置中注释/删除了某些应用(如 wezterm、alacritty)后,Launchpad 中仍然能看到这些应用的图标。
根本原因
Nix 的不可变 Store 设计 + 旧 generations 引用:
/nix/store/...-wezterm-xxx /nix/store/...-alacritty-yyy
▲ ▲
│ ┌──────────────┐ │
└─────────►│ home-manager-│◄───────────┘
│ applications │
└──────┬───────┘
│
┌─────────────────┼─────────────────┐
▼ ▼ ▼
system-1-link system-2-link system-3-link (current)
(旧 generation) (旧 generation) (只含 kitty)
旧 generations 继续引用已移除的应用,Launchpad 扫描所有可用应用时仍能发现它们。
Launchpad 扫描机制
Launchpad 扫描路径:
├── /Applications/
├── ~/Applications/
├── /nix/store/.../Applications/ (通过 Spotlight/Nix 链接)
└── ...
即使当前 generation 不包含 wezterm,只要 /nix/store 中还有它的 .app 且能被扫描到,Launchpad 就会显示它。
为什么注释配置 ≠ 删除应用
| 步骤 | 发生了什么 | 结果 |
|---|---|---|
| 1. 注释配置 | 修改 .nix 文件 | 配置文件改变 |
2. build-switch | Nix 构建新 generation | 创建 system-3-link |
| 3. 当前系统 | 切换到新 generation | 新配置生效 |
| 4. 旧 generations | system-1/2-link 仍然存在 | 继续引用旧包 |
| 5. 垃圾回收 | 未运行 | 旧包未被删除 |
关键点:只要还有任何 root 引用某个 store path,这个 path 就不会被删除。Generations 就是 gcroots,阻止被引用的包被回收。
排查思路
第一步:确认配置确实已修改
grep -r "wezterm\|alacritty" ~/github/self/bootstrap --include="*.nix"
# 输出:只有注释掉的行,说明配置已更新
第二步:确认应用实际位置
find /nix/store -maxdepth 3 -path "*wezterm*.app" -type d
find /nix/store -maxdepth 3 -path "*alacritty*.app" -type d
第三步:追踪引用链
# 查看应用被哪些 roots 引用
nix-store --query --roots /nix/store/<hash>-wezterm-xxx
如果输出指向旧 generations(如 system-1-link),说明是旧 generation 阻止了回收。
第四步:验证旧 generation 内容
ls -la /nix/store/<hash>-home-manager-applications/Applications/
解决方案
快速解决(推荐)
# 1. 确保配置已更新并应用
cd ~/github/self/bootstrap
sh scripts/aarch64-darwin/build-switch
# 2. 清理旧 generations 和无用包
sudo nix-collect-garbage -d
# 3. 重启 Dock 刷新 Launchpad
killall Dock
手动清理特定 generation
# 查看所有 system generations
sudo nix-env --list-generations --profile /nix/var/nix/profiles/system
# 删除特定 generation
sudo nix-env --delete-generations 1 2 --profile /nix/var/nix/profiles/system
# 或者只保留最近 3 个
sudo nix-env --delete-generations +3 --profile /nix/var/nix/profiles/system
# 运行垃圾回收
nix-collect-garbage
清理 home-manager generations
# 查看 home-manager generations
home-manager generations
# 清理旧的 home-manager generations
nix-collect-garbage -d
如果不处理会怎样?
配置中已启用自动 GC:
nix.gc = {
automatic = true;
interval = { Weekday = 0; Hour = 2; Minute = 0; }; # 每周日凌晨 2 点
options = "--delete-older-than 30d"; # 删除超过 30 天的 generations
};
| 操作 | 何时生效 | Launchpad 显示 |
|---|---|---|
| 注释配置 + build-switch | 立即 | 仍显示(旧 generation 引用) |
| 不做任何处理,等待自动 GC | 30 天后 | 仍显示(直到 GC 运行) |
手动运行 nix-collect-garbage -d | 立即 | 立即消失 |
为什么建议手动清理
- 30 天太长:不想等一个月才清理 Launchpad
- 磁盘空间:旧包占用空间(wezterm ~100MB,alacritty ~50MB)
- 视觉整洁:Launchpad 显示已不用的应用,造成困扰
验证
# 确认没有残留 roots
nix-store --gc --print-roots | grep -E "wezterm|alacritty"
# 确认 store 中相关包已清理
find /nix/store -maxdepth 1 -name "*wezterm*" -o -name "*alacritty*" 2>/dev/null
注意事项
- Generation 的作用:Generations 允许回滚到之前的系统状态,清理后无法回滚到被删除的 generation
- 定期清理:自动 GC 默认只删除超过 30 天的包,不会立即清理
- 如果 Launchpad 仍显示:
- 检查是否通过 Homebrew 单独安装:
brew list | grep -i wezterm - 检查
/Applications或~/Applications目录 - 手动删除残留:
rm -rf ~/Applications/Home\ Manager\ Apps/xxx.app
- 检查是否通过 Homebrew 单独安装:
相关命令速查
| 命令 | 作用 |
|---|---|
nix-collect-garbage -d | 删除旧 generations 并清理无用包 |
nix-store --gc --print-roots | 查看所有引用 store 包的 roots |
nix-store --query --roots /nix/store/... | 查看特定包被哪些 roots 引用 |
nix-env --list-generations --profile /nix/var/nix/profiles/system | 列出 system generations |
home-manager generations | 列出 home-manager generations |
find /nix/store -maxdepth 1 -name "*wezterm*" | 查找 store 中的残留包 |
Neovim Lua 模块缓存问题
问题表现
启动 Neovim 时,LSP 配置加载失败,报错如下:
Failed to load `plugins.lsp.lspconfig`
... module 'config.lsp.vuels' not found:
no field package.preload['config.lsp.vuels']
cache_loader: module 'config.lsp.vuels' not found
cache_loader_lib: module 'config.lsp.vuels' not found
关键特征:
- 错误指向的模块名(
vuels)与实际配置中的内容(vtsls)不符 - 使用了 Nix + Home Manager 管理 Neovim 配置
根本原因
Neovim 的 Lua 字节码缓存(.luac 文件)未正确刷新,导致加载了旧的编译结果。
LuaJIT/Lua 5.1 缓存机制
- Neovim 使用 LuaJIT 或 Lua 5.1
- 为加速启动,将 Lua 文件编译为字节码缓存到
~/.cache/nvim/luac/ - 缓存文件名经过 URL 编码
Nix 符号链接的复杂性
- 配置文件通过符号链接指向 Nix Store
- 当 Nix Store 路径变化时,缓存可能指向旧位置
- 文件内容变化但路径不变时,缓存检测机制可能失效
排查思路
第一步:验证配置文件内容
cat ~/.config/nvim/lua/config/lsp/init.lua
确认文件内容正确(如第 18 行应为 vtsls 而非 vuels)。
第二步:检查 Nix Store 中的文件
cat /nix/store/...-hm_conf/lua/config/lsp/init.lua
确认 Nix Store 中的文件也是正确的。
第三步:定位缓存问题
ls ~/.cache/nvim/luac/
缓存目录存在大量 .luac 文件,即使源文件已更新,缓存可能未同步刷新。
第四步:确认缓存机制
错误信息中 cache_loader: module 'config.lsp.vuels' not found 表明缓存系统参与了加载过程,加载了过期的字节码。
解决方案
快速解决(推荐)
# 清除 Lua 字节码缓存
rm -rf ~/.cache/nvim/luac
# 重启 Neovim
nvim
进阶解决
# 1. 清除所有 Neovim 缓存
rm -rf ~/.cache/nvim/
# 2. 清除 lazy.nvim 插件缓存(会重新下载插件)
rm -rf ~/.local/share/nvim/lazy/
# 3. 重启 Neovim
nvim
彻底清除(最后手段)
rm -rf ~/.cache/nvim/
rm -rf ~/.local/share/nvim/
rm -rf ~/.local/state/nvim/
nvim
预防措施
Home Manager 激活脚本
在 Nix 配置中添加自动清除缓存的激活脚本:
home.activation.clearNvimCache = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
rm -rf "${config.home.homeDirectory}/.cache/nvim/luac"
'';
Shell 别名
alias nvim-clean='rm -rf ~/.cache/nvim/luac && nvim'
常见场景速查
| 场景 | 症状 | 解决方法 |
|---|---|---|
| 修改 Lua 配置后未生效 | 配置更改但行为不变 | rm -rf ~/.cache/nvim/luac |
| 移动/重命名 Lua 模块 | 模块找不到错误 | rm -rf ~/.cache/nvim/luac |
| Nix 配置切换后异常 | 插件加载失败、配置混乱 | rm -rf ~/.cache/nvim/ |
| 插件更新后出错 | 插件功能异常、报错 | rm -rf ~/.local/share/nvim/lazy/ |
| 完全混乱无法启动 | 多种错误交织 | 彻底清除所有缓存 |
技术细节
缓存文件命名
缓存文件名是原始路径的 URL 编码:
- 原始路径:
/Users/moonshot/.config/nvim/lua/config/lsp/init.lua - 缓存名:
%2fUsers%2fmoonshot%2f.config%2fnvim%2flua%2fconfig%2flsp%2finit.luac
加载优先级
package.preload— 预加载表cache_loader— 字节码缓存加载器cache_loader_lib— 库缓存加载器- 文件系统搜索 — 原始
.lua文件
错误信息中的顺序反映了 Neovim 的模块加载尝试顺序。
参考信息
| 目录 | 说明 |
|---|---|
~/.cache/nvim/luac/ | Lua 字节码缓存 |
~/.local/share/nvim/lazy/ | lazy.nvim 插件目录 |
~/.local/state/nvim/ | LSP 日志等状态文件 |
| 相关技术 | LuaJIT, Lua 5.1, Nix, Home Manager |
修复 rust-analyzer 不报错
问题表现
在 Neovim 中编辑 Rust 文件时,即使代码有明显语法错误,rust-analyzer 也不显示任何诊断信息。
根本原因
rust-analyzer 无法加载 workspace,整个 LSP 分析功能静默失效。具体有两个问题:
1. Cargo 版本冲突
系统中存在多个 cargo,rust-analyzer 调用了旧版:
| 来源 | 路径 | 版本 |
|---|---|---|
| rustup(旧) | ~/.cargo/bin/cargo | 1.84.0 ❌ |
| Nix(散装) | ~/.nix-profile/bin/cargo | 1.89.0 ✅ |
项目 Cargo.toml 指定 edition = "2024"(需要 Cargo ≥ 1.85),旧版 cargo 直接报错。
2. 缺少 rust-src
Nix 单独安装的 pkgs.rustc 不包含标准库源码,rust-analyzer 在 sysroot 下找不到 lib/rustlib/src/rust/library/。
排查思路
查看 LSP 日志
cat ~/.local/state/nvim/lsp.log | grep -i "rust.*error" | tail -20
关键错误信息:
ERROR FetchWorkspaceError: rust-analyzer failed to load workspace
ERROR can't load standard library, try installing `rust-src`
检查工具链
which -a cargo # 是否有多个 cargo
cargo --version # 当前版本是否够新
SYSROOT=$(rustc --print sysroot)
ls "$SYSROOT/lib/rustlib/src/rust/library/" # rust-src 是否存在
解决方案
用 fenix 替换散装 Rust 包,提供包含 rust-src 的完整工具链。
修改 modules/macos/packages.nix
Before:
{ config, pkgs, ... }:
let
RUST_DEVELOPMENT_PACKAGES = with pkgs; [
rustc
cargo
clippy
rust-analyzer
rustfmt
];
After:
{ config, pkgs, inputs, ... }:
let
fenixPkgs = inputs.fenix.packages.${pkgs.system};
rust-toolchain = (fenixPkgs.toolchainOf {
channel = "stable";
date = "2025-09-18";
sha256 = "sha256-SJwZ8g0zF2WrKDVmHrVG3pD2RGoQeo24MEXnNx5FyuI=";
root = "https://mirrors.ustc.edu.cn/rust-static/dist";
}).withComponents [
"cargo"
"clippy"
"rustc"
"rustfmt"
"rust-src"
"rust-analyzer"
];
RUST_DEVELOPMENT_PACKAGES = [
rust-toolchain
];
添加 fenix cachix 缓存
hosts/darwin.nix:
substituters = [
"https://nix-community.cachix.org"
"https://cache.nixos.org"
"https://fenix.cachix.org"
];
trusted-public-keys = [
"cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY="
"fenix.cachix.org-1:PpL1UNHViEFrcJzCDV+yl+S+c90I5hTqGq0G+1RP0wM="
];
~/.config/nix/nix.conf(用户级,立即生效):
substituters = https://cache.nixos.org https://nix-community.cachix.org https://fenix.cachix.org
trusted-public-keys = cache.nixos.org-1:... nix-community.cachix.org-1:... fenix.cachix.org-1:PpL1UNHViEFrcJzCDV+yl+S+c90I5hTqGq0G+1RP0wM=
Apply
cd ~/github/self/bootstrap && sh scripts/aarch64-darwin/build-switch
验证
rustc --version && cargo --version && rust-analyzer --version
SYSROOT=$(rustc --print sysroot)
ls "$SYSROOT/lib/rustlib/src/rust/library/"
# 应看到 alloc, core, std 等目录
清理旧的 rustup
rustup self uninstall # 如果 command not found 则无需操作
构建踩坑
下载卡住
fenix 首次构建需从 static.rust-lang.org 下载工具链 tarball,国内可能很慢。
手动从 USTC 镜像下载后替换:
# 从镜像下载
curl -L -o /tmp/rustc.tar.gz \
"https://mirrors.ustc.edu.cn/rust-static/dist/<date>/rustc-<ver>-aarch64-apple-darwin.tar.gz"
curl -L -o /tmp/rust-std.tar.gz \
"https://mirrors.ustc.edu.cn/rust-static/dist/<date>/rust-std-<ver>-aarch64-apple-darwin.tar.gz"
# 停 daemon,替换,重启
sudo launchctl bootout system/org.nixos.nix-daemon
sudo pkill -9 -u _nixbld1 2>/dev/null
sudo pkill -9 -u _nixbld10 2>/dev/null
sudo cp /tmp/rustc.tar.gz /nix/store/<hash>-rustc-<ver>-aarch64-apple-darwin.tar.gz
sudo cp /tmp/rust-std.tar.gz /nix/store/<hash>-rust-std-<ver>-aarch64-apple-darwin.tar.gz
sudo rm -f /nix/store/<hash>*.lock
sudo launchctl bootstrap system /Library/LaunchDaemons/org.nixos.nix-daemon.plist
sleep 3 && nix store ping
store 路径中的
<hash>从 build 日志的waiting for lock on行中获取。
daemon 残留进程
之前中断的 build 可能在 daemon 中残留,重启后自动恢复并占用 worker。
sudo launchctl bootout system/org.nixos.nix-daemon
sudo pkill -9 -u _nixbld1 2>/dev/null
sudo pkill -9 -u _nixbld10 2>/dev/null
sudo rm -f /nix/store/<hash>*.lock
sudo rm -f /nix/store/<hash>-rustc-*.tar.gz
sudo launchctl bootstrap system /Library/LaunchDaemons/org.nixos.nix-daemon.plist
Connection refused
daemon 还没启动完就执行了 nix 命令,等几秒再试:
sleep 3 && nix store ping
更新工具链版本
rust-toolchain = (fenixPkgs.toolchainOf {
channel = "stable";
date = "<新日期>";
sha256 = lib.fakeSha256; # 先用假 hash
root = "https://mirrors.ustc.edu.cn/rust-static/dist";
}).withComponents [ ... ];
构建报错会给出正确的 sha256,替换后再次构建即可。
FAQ
一般问题
Q: Bootstrap 支持哪些平台?
A: 目前 macOS (nix-darwin) 完全支持,NixOS 支持正在开发中。
| 平台 | 架构 | 状态 |
|---|---|---|
| macOS | aarch64-darwin, x86_64-darwin | ✅ 可用 |
| NixOS | x86_64-linux, aarch64-linux | 🚧 开发中 |
Q: 如何更新系统配置?
A: 修改 .nix 文件后运行:
cd scripts
sh ./aarch64-darwin/build-switch
Q: 如何回滚到之前的配置?
A:
cd scripts
sh ./aarch64-darwin/rollback
或者使用 nix-darwin 命令:
sudo darwin-rebuild switch --flake .#aarch64-darwin
Q: 如何添加新的软件包?
A: 编辑 modules/common/packages.nix,在对应的包组中添加包名,然后运行 build-switch。
Nix 相关问题
Q: Flakes 是什么?
A: Flakes 是 Nix 的实验性功能,提供:
- 可复现的依赖管理(通过
flake.lock) - 标准化的 Nix 表达式接口
- 更好的缓存和共享
Q: 如何更新 flake 输入?
A:
nix flake update
更新特定输入:
nix flake lock --update-input nixpkgs
Q: build-switch 和 build 有什么区别?
A:
build— 仅构建配置,生成result链接,不切换系统build-switch— 构建并立即切换到新配置
Q: attribute 'inputs' missing 错误怎么办?
A: 这个错误发生在 modules/common/ 需要 inputs(用于 fenix Rust 工具链)但没有正确传递时。确保以下三个地方都正确传递了 inputs:
-
flake.nix中的extraSpecialArgs:extraSpecialArgs = { inherit inputs; axiomIdentity = inventory.identity; }; -
home.nix的模块参数:{ axiomIdentity, pkgs, inputs, ... }: -
modules/macos/home-manager.nix的模块参数和extraSpecialArgs:{ axiomIdentity, inputs, ... }: { home-manager.extraSpecialArgs = { inherit axiomIdentity inputs; }; }
故障排查
Q: Launchpad 显示已删除的应用?
A: 参见 清理 Launchpad 残留图标。
Q: Neovim 配置修改后不生效?
A: 参见 Neovim Lua 缓存问题。
Q: rust-analyzer 不报错?
A: 参见 修复 rust-analyzer 不报错。
Q: 构建失败怎么办?
A:
- 检查
flake.nix语法:nix flake check - 查看详细错误:
sh ./aarch64-darwin/build-switch --show-trace - 更新 flake 输入:
nix flake update - 清理构建缓存:
nix-collect-garbage -d
常用命令
Nix 基础
| 命令 | 说明 |
|---|---|
nix --version | 查看 Nix 版本 |
nix flake check | 检查 flake 配置 |
nix flake update | 更新所有 flake 输入 |
nix flake lock --update-input <name> | 更新特定输入 |
nix-collect-garbage -d | 删除旧 generations 并清理 |
nix-store --gc --print-roots | 查看 gc roots |
nix-shell -p <pkg> | 临时进入含某包的 shell |
Bootstrap 构建
| 命令 | 说明 |
|---|---|
sh ./aarch64-darwin/build | 仅构建 |
sh ./aarch64-darwin/build-switch | 构建并切换 |
sh ./aarch64-darwin/rollback | 回滚配置 |
sh ./aarch64-darwin/apply | 交互式应用配置 |
nix-darwin
| 命令 | 说明 |
|---|---|
darwin-rebuild switch --flake .#<host> | 切换配置 |
darwin-rebuild build --flake .#<host> | 仅构建 |
darwin-rebuild changelog --flake .#<host> | 查看更新日志 |
Home Manager
| 命令 | 说明 |
|---|---|
home-manager switch --flake .#<user> | 切换用户配置 |
home-manager generations | 查看 generations |
home-manager news | 查看更新信息 |
模板使用
| 命令 | 说明 |
|---|---|
nix flake init -t github:BeauvnTu/Bootstrap#<template> | 初始化项目 |
nix flake init -t github:BeauvnTu/Bootstrap#deno | Deno 项目 |
nix flake init -t github:BeauvnTu/Bootstrap#rust-wasm | Rust + WASM 项目 |
文档开发
| 命令 | 说明 |
|---|---|
nix develop -c zsh | 进入 docs devShell |
mdbook serve docs | 本地预览文档 |
mdbook build docs | 构建文档 |
🛠️ 开发工具推荐
一份精心整理的开发者必备软件、框架和工具集,帮助你在不同平台和环境下高效地构建、测试、调试和部署应用。
Windows 专属
- Scoop:Windows 包管理器,命令行安装软件。
- Bandizip:强大的压缩/解压工具,免费版功能已很完善。
- Visual Studio:微软官方 IDE,功能全面。
macOS 专属
- Homebrew:macOS 包管理器(本项目通过 nix-homebrew 集成)。
- Xcode:开发 Apple 平台应用的官方 IDE。
- Kitty:基于 GPU 的高性能终端模拟器。
- Ghostty:用 Zig 编写的现代化终端模拟器,启动速度快,渲染性能优秀。
编辑器
- Neovim:Vim 的现代化分支,插件生态丰富。
- VS Code:目前最流行的编辑器,插件生态极其丰富。建议安装
code命令以便快速启动。 - Cursor:基于 VS Code 的 AI 编辑器,代码辅助能力强大。
- Zed:高性能编辑器,但插件生态相对有限。
- Sublime Text:轻量、快速、跨平台的代码编辑器,界面简洁。
- Android Studio:Google 官方 Android 开发 IDE,内置模拟器和调试工具,适用于 Windows、macOS 和 Linux 上的完整 Android 开发工作流。
- Xcode:Apple 官方 macOS/iOS 开发 IDE,仅 macOS 可用。集成代码编辑、UI 设计、模拟器、调试和发布工具,是 Apple 生态开发的必备工具。
- Fleet:JetBrains 下一代 IDE,支持 AI 辅助和分布式协作开发。
浏览器
- Chrome:Google 浏览器,开发者工具完善。
- Arc Browser:以标签页管理体验著称的浏览器。
- Edge:微软浏览器,基于 Chromium。
开发工具
- Git:版本控制工具。macOS 自带,Windows 需自行安装:
scoop install git - Vim:文本编辑器。macOS 自带,Windows 需自行安装:
scoop install vim - NVM:Node.js 版本管理器。
# macOS 可通过 nix-homebrew 安装 # Windows scoop bucket add main scoop install nvm - Node.js:JavaScript 运行时,配合 NVM 可安装多版本。安装后自动附带 npm。
- Android Studio:构建 Android 平台应用。
- SwitchHosts:Hosts 文件管理工具。
- Synergy:一套键鼠控制多台电脑。
- Docker:容器化平台,简化应用构建和部署。
- OrbStack:macOS 上 Docker Desktop 的轻量替代品,启动极快,资源占用低,同时支持容器和 Linux 虚拟机。
# macOS 可通过 nix-homebrew 安装 # Windows scoop install docker - tig:基于 ncurses 的 Git 文本界面,适合浏览仓库和分块提交。
# macOS 可通过 nix-homebrew 安装 # Windows scoop install tig - Charles:HTTP/HTTPS 代理和抓包工具。
- Wireshark:网络协议深度分析工具。
- Postman:API 开发平台,用于测试、文档化和协作 REST/GraphQL 接口。
- Fork:简洁易用的 Git 图形客户端。
AI 助手
- ChatGPT:AI 对话助手,可用于编程求助、问题解决和创意任务。
- Claude Code:Anthropic 推出的终端 AI 编程助手,支持代码编辑、调试和自动化任务。
- Codex:OpenAI 官方 CLI 工具,基于 GPT-4o 的终端 AI 编程助手。
- Lark CLI:飞书(Lark)官方命令行工具,用于开发和管理飞书应用。
- Kimi Code CLI:月之暗面(Moonshot AI)推出的终端 AI 编程助手,支持代码读写、Shell 命令执行、网页搜索和自主任务规划。
- OpenClaw:AI 驱动的 CLI 工具,支持多种 AI 模型和自动化工作流。