Resources
https://nixos.org/manual/nixpkgs/stable/
https://nix.dev/manual/nix/2.32/
https://nix.dev/tutorials/
https://nix.dev/reference/
https://nix.dev/guides/
https://nix.dev/concepts/
nixos-and-flakes-book
Concepts
flake
flake.nix 核心文件
</home/disk/Dev/hlissner-dotfiles/flake.nix>
• flake.nix 是 Nix flake 的“入口文件”,在这个仓库里基本就是整套配置的中枢,大致做这些事:
- 声明依赖 (inputs)
比如用到的 Nixpkgs 版本、外部 flake(home-manager 等),都在 flake.nix 里统一锁定和引用。 - 导出结果 (outputs)
定义这个仓库对外提供什么:
- NixOS 主机配置(hosts/ 下的机器)
- 模块、包、overlay、devShell 等
这样你可以用 nix build、nix flake check、nix develop 等直接调用。
- NixOS 主机配置(hosts/ 下的机器)
- 自动发现项目结构
按本仓库的约定,它会自动发现并挂上:
- hosts/ 里的主机
- modules/ 里的模块
- packages/ 里的包
- overlays/、test/ 等
- hosts/ 里的主机
- 给工具链提供统一入口
像 bin/hey sync、bin/hey build、nix flake check、nix develop 等命令,最终都是围绕 flake.nix 中的定义在跑。
简单说:flake.nix 定义了“这套 dotfiles/系统配置由哪些依赖组成、导出哪些配置和命令”,其它目录 (hosts/, modules/ 等) 都是被它组织起来的。
module
在 NixOS / home-manager 体系里,module = 一块可组合的配置单元,专门用来描述“这个功能需要哪些选项、怎么启用”。
更形式化一点,一个 Nix 模块基本就是这样的函数:
{ config, lib, pkgs, ... }:
let
cfg = config.modules.desktop.hyprland;
in {
# 1. 声明这个模块有哪些配置项(options)
options.modules.desktop.hyprland.enable = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Enable Hyprland desktop.";
};
# 2. 根据这些配置项,实际写系统配置(config)
config = lib.mkIf cfg.enable {
services.xserver.enable = true;
# ...
};
}可以这样理解:
- options:声明“我提供哪些设置”
- 起名:modules.desktop.hyprland.enable 这种 kebab-case 分层命名。
- 指明类型(bool/string/list)、默认值、说明等。
- 其它模块/主机就可以设置这些选项,比如 modules.desktop.hyprland.enable = true;。
- 起名:modules.desktop.hyprland.enable 这种 kebab-case 分层命名。
- config:根据选项生成最终系统配置
- 里面通常写的是 NixOS / home-manager 的标准选项:比如 services.*, users.*, programs.*。
- 多个 module 可以同时给同一个 config.services.sshd 之类的字段赋值,Nix 会按规则自动合并(列表拼接、attrset 合并等)。
- 里面通常写的是 NixOS / home-manager 的标准选项:比如 services.*, users.*, programs.*。
- 模块是“可合并的配置片段”
- 顶层会把所有模块(官方模块、自定义模块、host 自己写的模块)收集起来,一起 merge 成一个巨大的 config。
- 你不需要有“主配置文件把所有内容写满”,而是拆成很多小模块,每个模块负责一个功能/子系统。
- 顶层会把所有模块(官方模块、自定义模块、host 自己写的模块)收集起来,一起 merge 成一个巨大的 config。
overlay
pakcages
nix cli
develop
nix develop builds a development shell defined by a flake (or shell.nix) and drops you into it with the declared tools on PATH.
What it does here
- Evaluates devShells.<system>.default in flake.nix.
- Builds required Nix packages (python, sdcv, mpv, etc.), then runs the shellHook.
- In our flake, shellHook sets NLTK_DATA/PATH, creates a local .venv on first run, installs the pip-only bits, and downloads NLTK data.
- You get an interactive shell with all those tools available; they vanish when you exit.
Common flags
- nix develop (no args): uses devShells.<system>.default in flake.nix in the current dir.
- nix develop .#name: pick a specific devShell output (e.g., .#default or .#docs).
- nix develop —command <cmd> …: run one command inside the dev shell without opening an interactive shell.
- nix develop —impure: allow environment variables from your session to pass through (useful if the flake wants them).
- nix develop —accept-flake-config: needed if the flake sets nixConfig options and you trust them.
How it differs from nix shell
- nix shell only provides packages; nix develop also runs shellHook and honors a richer dev environment description (useful for bootstrapping venvs, exporting vars, etc.).
Typical workflow
- nix develop inside the repo.
- Work; the PATH and env are already set up.
- Exit with exit/Ctrl-D—your global system stays untouched.