Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Bootstrap

One Flake to Rule Them All – for macOS (nix-darwin), NixOS, and home-manager.

克隆仓库,运行一条命令,看着你的系统按你的意愿配置好。不再有配置混乱,有更多时间做重要的事——比如看着终端自动配置时品一杯咖啡。

✨ git clone 你的理智之路
⚡ nix run 你的荣耀之路


特性

  • 零启动脚本 — 纯 nix 命令,无需额外脚本
  • 多主机、多用户 — 所有机器配置集中在一个仓库
  • 确定性 — lock 文件锁定每一个比特
  • 模块化 — 自由组合 common 模块(gitzshtmux…)
  • 项目模板nix flake init -t 脚手架,支持 Deno、Java、Rust+WASM
  • 独立 Home Manager — 不依赖 nix-darwin,通过 home-manager switch --flake 使用

支持平台

平台架构状态
macOS (nix-darwin)aarch64-darwin, x86_64-darwin✅ 可用
NixOSx86_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)

输入用途
nixpkgsNix 包集合 (nixos-unstable)
home-manager用户环境管理
darwinnix-darwin (macOS 系统配置)
nix-homebrewNix 管理 Homebrew
homebrew-bundle/core/caskHomebrew 相关
disko声明式磁盘分区 (NixOS)
fenixRust 工具链

输出 (Outputs)

Apps

每个平台都有一组便捷的构建命令:

Linux Apps:

  • apply
  • build-switch
  • copy-keys
  • create-keys
  • check-keys
  • install

Darwin Apps:

  • apply
  • build
  • build-switch
  • copy-keys
  • create-keys
  • check-keys
  • rollback

Darwin Configurations

macOS 系统配置由 hosts/darwin.nix 导入,支持 aarch64-darwinx86_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-linux
  • aarch64-linux
  • aarch64-darwin
  • x86_64-darwin

当前唯一的 devShell 是 default,包含 mdbook 用于构建文档。

Templates

项目模板通过 templates/default.nix 引入:

templates = import ./templates;

可用模板:

  • deno — Deno 运行时
  • java — JDK 17 + Maven + Gradle
  • rust-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-darwinx86_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)共同导入。

包含模块

模块说明
GitGit 配置
Tmux终端复用器配置
ZshZsh Shell 配置

包管理

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 版本控制工具的配置。

基础配置

选项说明
userNameaxiomIdentity.gitName从身份模块读取
userEmailaxiomIdentity.gitEmail从身份模块读取
init.defaultBranchmain默认分支名
core.editorvim默认编辑器
core.autocrlfinput行尾符处理
pull.rebasetruepull 时使用 rebase
rebase.autoStashtruerebase 前自动 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 配置,建议:

  1. modules/common/ 下创建 neovim.nix
  2. modules/common/default.nix 中导入
  3. 或使用独立的 Neovim 配置仓库(如 nvim-lua/kickstart.nvim

当前状态

仓库中没有 modules/common/vim/ 目录。modules/common/default.nix 仅导入:

  • git.nix
  • zsh.nix
  • tmux.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

别名

别名命令
diffdifft (语法感知的 diff)
lsls -G
llls -la
lals -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 用户环境。

配置

选项说明
useGlobalPkgstrue使用全局 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 的所有输入(用于 fenix Rust 工具链等)

其他设置

  • 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 开发

说明
goGo 编译器
gotagsctags for Go
goplsGo LSP
delveGo 调试器
go-toolsGo 工具集
gotestsum测试输出美化

Rust 开发

通过 fenix 提供完整工具链:

组件说明
cargo包管理器
clippyLinter
rustc编译器
rustfmt格式化
rust-src标准库源码(rust-analyzer 需要)
rust-analyzerLSP

使用 USTC 镜像加速下载:

fenixPkgs.toolchainOf {
  channel = "stable";
  date = "2025-09-18";
  sha256 = "sha256-SJwZ8g0zF2WrKDVmHrVG3pD2RGoQeo24MEXnNx5FyuI=";
  root = "https://mirrors.ustc.edu.cn/rust-static/dist";
}

JavaScript 开发

说明
nodejs_22Node.js
pnpm包管理器

Python

说明
uv极速 Python 包管理器
python3Python 解释器

Lua

说明
luaLua 解释器
luarocksLua 包管理器

基础开发工具

说明
git, git-lfs, tig版本控制
ripgrep, fd, fzf搜索工具
universal-ctags代码标签
neovim编辑器
gcc, gnumake编译工具
lazygitTUI Git
chezmoi点文件管理
helix模态编辑器
dockerfile-language-server-nodejsDockerfile LSP

系统工具

说明
bat增强 cat
tree目录树
coreutilsGNU 核心工具
zip, unzip压缩工具

系统级字体 (hosts/darwin.nix)

hosts/darwin.nix 中配置的系统级字体:

说明
hack-fontHack 字体
meslo-lgs-nfMeslo Nerd Font
noto-fontsNoto 字体
noto-fonts-emojiEmoji 字体
nerd-fonts.roboto-monoRoboto Mono Nerd Font
powerlinePowerline 字体

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 仓库实际位置调整。

可用模板

模板说明使用
DenoDeno 运行时nix flake init -t github:BeauvnTu/Bootstrap#deno
JavaJDK 17 + Maven + Gradlenix flake init -t github:BeauvnTu/Bootstrap#java
Rust + WASMRust + WebAssemblynix flake init -t github:BeauvnTu/Bootstrap#rust-wasm

通用特性

所有模板都支持以下平台:

  • aarch64-darwin (Apple Silicon)
  • x86_64-darwin (Intel Mac)
  • aarch64-linux
  • x86_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";
    };
    # ...
  };
}

自定义模板

如需添加新模板:

  1. templates/ 下创建新目录(如 templates/my-template/
  2. 编写 flake.nix(project 级别)
  3. 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 怎么办?

只需:

  1. 安装 Nix(https://nixos.org/download
  2. 进入项目目录执行 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

包含

说明
denoDeno 运行时

文件

templates/deno/flake.nix

Java

Java 开发环境模板,基于 JDK 17,附带 Maven 和 Gradle 构建工具。

使用

nix flake init -t github:BeauvnTu/Bootstrap#java

包含工具

说明
jdk17Java 17 JDK
mavenMaven 构建工具
gradleGradle 构建工具

初始化后

# 进入开发环境
nix develop

# 验证版本
java -version
mvn -version
gradle -version

Rust + WebAssembly

Rust WebAssembly 开发环境模板。

使用

nix flake init -t github:BeauvnTu/Bootstrap#rust-wasm

包含

说明
stable.toolchainRust 稳定版工具链
wasm32-unknown-unknownWASM 目标
wasm-packWASM 打包工具
binaryenWASM 优化工具
wabtWASM 二进制工具
lldLLVM 链接器
git版本控制
nodejs_20Node.js
rust-analyzerRust LSP

环境变量

变量
EDITORvim
WASM_PACK_CACHE_DIR$HOME/.wasm-pack
CARGO_TARGET_WASM32_UNKNOWN_UNKNOWN_LINKERlld

脚本概览

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-linuxx86_64-linux 的符号链接。

脚本说明

build-switch

构建并切换到新配置(最常用):

cd scripts
sh ./aarch64-darwin/build-switch

流程:

  1. nix build .#darwinConfigurations.aarch64-darwin.system
  2. sudo darwin-rebuild switch --flake .#aarch64-darwin
  3. 清理 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-switchNix 构建新 generation创建 system-3-link
3. 当前系统切换到新 generation新配置生效
4. 旧 generationssystem-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 引用)
不做任何处理,等待自动 GC30 天后仍显示(直到 GC 运行)
手动运行 nix-collect-garbage -d立即立即消失

为什么建议手动清理

  1. 30 天太长:不想等一个月才清理 Launchpad
  2. 磁盘空间:旧包占用空间(wezterm ~100MB,alacritty ~50MB)
  3. 视觉整洁: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

注意事项

  1. Generation 的作用:Generations 允许回滚到之前的系统状态,清理后无法回滚到被删除的 generation
  2. 定期清理:自动 GC 默认只删除超过 30 天的包,不会立即清理
  3. 如果 Launchpad 仍显示
    • 检查是否通过 Homebrew 单独安装:brew list | grep -i wezterm
    • 检查 /Applications~/Applications 目录
    • 手动删除残留:rm -rf ~/Applications/Home\ Manager\ Apps/xxx.app

相关命令速查

命令作用
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

加载优先级

  1. package.preload — 预加载表
  2. cache_loader — 字节码缓存加载器
  3. cache_loader_lib — 库缓存加载器
  4. 文件系统搜索 — 原始 .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/cargo1.84.0 ❌
Nix(散装)~/.nix-profile/bin/cargo1.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 支持正在开发中。

平台架构状态
macOSaarch64-darwin, x86_64-darwin✅ 可用
NixOSx86_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

  1. flake.nix 中的 extraSpecialArgs

    extraSpecialArgs = {
      inherit inputs;
      axiomIdentity = inventory.identity;
    };
    
  2. home.nix 的模块参数:

    { axiomIdentity, pkgs, inputs, ... }:
    
  3. 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:

  1. 检查 flake.nix 语法:nix flake check
  2. 查看详细错误:sh ./aarch64-darwin/build-switch --show-trace
  3. 更新 flake 输入:nix flake update
  4. 清理构建缓存: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#denoDeno 项目
nix flake init -t github:BeauvnTu/Bootstrap#rust-wasmRust + 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 模型和自动化工作流。