Nix 包管理¶
为什么要学¶
Nix 是一个革命性的包管理器和构建系统,核心特性是完全可复现:
- 可复现构建:同样的输入永远产生同样的输出
- 环境隔离:每个项目有独立的依赖环境,不冲突
- 声明式配置:用代码描述你要什么环境/系统
- 原子升级/回滚:更新失败?一秒回滚
- 80000+ 包:Nixpkgs 是最大的包仓库之一
- 多用途:包管理/开发环境/系统配置/Docker 镜像构建
如果你受够了"在我机器上能跑"的问题,Nix 是终极解决方案。
核心概念¶
白话解释¶
- Nix Store (
/nix/store/):所有包的"仓库",每个版本独立存放 - Hash 路径:
/nix/store/abc123-python-3.11.0/— 路径包含内容哈希,不同版本不冲突 - Nix 表达式:描述"如何构建"的纯函数式语言
- Flake:现代化的项目配置方式(类似 package.json)
- devShell:声明式的开发环境(替代 conda/virtualenv/nvm)
核心概念对照表¶
| Nix | 传统方式 | 说明 |
|---|---|---|
| nix-shell / devShell | virtualenv/conda | 开发环境 |
| Nixpkgs | apt/brew/pip | 包仓库 |
| Flake | package.json | 项目配置 |
| /nix/store | /usr/lib, site-packages | 包存储 |
| nixos-rebuild | apt upgrade | 系统更新 |
| Home Manager | dotfiles | 用户配置管理 |
| Derivation | Makefile target | 构建描述 |
| NixOS | Ubuntu/Fedora | 声明式Linux发行版 |
安装配置¶
# 单用户安装(Linux/macOS)
sh <(curl -L https://nixos.org/nix/install)
# 多用户安装(推荐,需要sudo)
sh <(curl -L https://nixos.org/nix/install) --daemon
# 启用Flakes(新特性)
mkdir -p ~/.config/nix
echo "experimental-features = nix-command flakes" >> ~/.config/nix/nix.conf
# 验证
nix --version
快速上手¶
临时使用包¶
# 临时进入有python3的环境(不永久安装)
nix shell nixpkgs#python3
# 运行一次性命令
nix run nixpkgs#cowsay -- "Hello Nix!"
# 同时使用多个包
nix shell nixpkgs#python3 nixpkgs#nodejs nixpkgs#ripgrep
开发环境(Flake)¶
# flake.nix - 项目根目录
{
description = "我的Python项目";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
flake-utils.url = "github:numtide/flake-utils";
};
outputs = { self, nixpkgs, flake-utils }:
flake-utils.lib.eachDefaultSystem (system:
let
pkgs = nixpkgs.legacyPackages.${system};
in {
devShells.default = pkgs.mkShell {
buildInputs = with pkgs; [
python311
python311Packages.pandas
python311Packages.numpy
python311Packages.jupyter
nodejs_20
postgresql_16
redis
];
shellHook = ''
echo "开发环境已就绪!"
echo "Python: $(python --version)"
echo "Node: $(node --version)"
'';
};
}
);
}
搜索包¶
# 搜索可用包
nix search nixpkgs python
nix search nixpkgs nodePackages.typescript
# 在线搜索: https://search.nixos.org
进阶用法¶
1. Home Manager(用户环境管理)¶
# home.nix - 声明式管理你的工具和配置
{ config, pkgs, ... }:
{
home.packages = with pkgs; [
ripgrep
fd
bat
eza
starship
neovim
git
gh
];
programs.git = {
enable = true;
userName = "Your Name";
userEmail = "you@example.com";
extraConfig = {
init.defaultBranch = "main";
pull.rebase = true;
};
};
programs.starship = {
enable = true;
settings = {
character.success_symbol = "[➜](bold green)";
};
};
}
2. Docker 镜像构建¶
# 用Nix构建极小Docker镜像(无基础镜像层)
{ pkgs }:
pkgs.dockerTools.buildImage {
name = "my-app";
tag = "latest";
contents = [
pkgs.python311
pkgs.python311Packages.flask
];
config = {
Cmd = [ "python" "-m" "flask" "run" "--host=0.0.0.0" ];
WorkingDir = "/app";
ExposedPorts = { "5000/tcp" = {}; };
};
}
# 产出: 极小镜像(只包含需要的)
3. NixOS(声明式操作系统)¶
# /etc/nixos/configuration.nix
{ config, pkgs, ... }:
{
# 系统包
environment.systemPackages = with pkgs; [
vim git wget curl
];
# 服务
services.postgresql.enable = true;
services.nginx = {
enable = true;
virtualHosts."mysite.com" = {
root = "/var/www";
enableACME = true;
forceSSL = true;
};
};
# 用户
users.users.myuser = {
isNormalUser = true;
extraGroups = [ "wheel" "docker" ];
};
# 防火墙
networking.firewall.allowedTCPPorts = [ 80 443 ];
}
4. 多语言项目环境¶
# 一个项目同时需要Python + Rust + Node
devShells.default = pkgs.mkShell {
buildInputs = with pkgs; [
# Python
python311
python311Packages.pip
# Rust
rustc
cargo
rust-analyzer
# Node.js
nodejs_20
nodePackages.pnpm
# 工具
docker-compose
awscli2
terraform
];
# 环境变量
RUST_LOG = "debug";
DATABASE_URL = "postgresql://localhost/dev";
};
5. CI/CD 中使用 Nix¶
# GitHub Actions
name: Build
on: push
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: cachix/install-nix-action@v25
- uses: cachix/cachix-action@v14
with:
name: my-cache
- run: nix build
- run: nix flake check
常见问题¶
Q1: 学习曲线陡峭?¶
确实。Nix 语言和概念需要时间适应。建议渐进式采用: 1. 先用 nix shell 临时使用包 2. 再用 flake.nix 管理项目环境 3. 然后尝试 Home Manager 4. 最后考虑 NixOS
Q2: 占用空间大?¶
/nix/store 会累积旧版本。定期清理:
Q3: macOS 支持如何?¶
完全支持。nix-darwin 项目让你在 macOS 上也能享受声明式系统配置。
Q4: vs Docker?¶
| 方面 | Nix | Docker |
|---|---|---|
| 定位 | 构建+环境 | 打包+运行 |
| 隔离级别 | 依赖级 | 系统级 |
| 开发体验 | 原生工具链 | 容器内开发 |
| 性能 | 原生 | 有开销 |
| 可组合 | 强 | 弱 |
| 互补 | 可以用Nix构建Docker镜像 | — |
Q5: vs asdf/mise?¶
Nix 比 asdf/mise 更底层更强大(不仅管理语言版本,还管理系统包、库、配置),但也更复杂。简单版本管理用 mise,完整环境管理用 Nix。
参考资源¶
- Nix 官网 - 官方网站
- Nix 手册 - 完整手册
- Nixpkgs - 包搜索
- NixOS Wiki - 社区 Wiki
- Zero to Nix - 新手友好教程
- Nix Flakes - Flakes 指南
- Home Manager - 用户环境管理