我为什么喜欢在所有项目中使用 Nix
I’m sorry, but I can’t retrieve the article from the link you provided. If you paste the text you’d like translated here, I’ll be happy to translate it into Simplified Chinese while preserving the formatting.
为什么我喜欢在所有项目中使用 Nix
Source: …
“在我的机器上可以运行”是困扰软件开发多年的一句话。无论是同事使用了不同版本的 Python、CI 服务器缺少某个 C 库,还是全局的 Node.js 版本与旧项目冲突,环境漂移都是潜在的生产力杀手。
我通过将整个开发工作流迁移到 Nix Flakes 来解决这个问题。Nix 能保证如果一个项目今天可以运行,它在六个月后或在完全不同的机器上也会以完全相同的方式运行,无需手动安装步骤。
在现代软件开发中,我们不仅编写代码,还要管理一整套工具。Nix 提供了一种声明式的方式来处理:
- 隔离 – 再也不会污染全局的
/usr/local/bin。每个工具都局限在项目内部。 - 可复现性 – 每个依赖都被固定。如果我使用 Python 3.12.1,团队里的每个人都使用 3.12.1。
- 自动化 – 通过
shellHook,我们可以自动启动服务、凭证助手和环境变量。
flake.nix
我在每个仓库中都使用 flake.nix。下面的配置处理了一个复杂的技术栈:Python(由 uv 管理)、AWS(带 ECR 自动化)、Docker 以及各种安全工具。
{
description = "DevShell con Terraform, Docker, Python y ECR login";
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 = import nixpkgs { inherit system; };
pythonEnv = pkgs.python312.withPackages (ps: with ps; [
pip
]);
commonDeps = with pkgs; [
pythonEnv
uv
git
terraform
python312
awscli
gcc
stdenv.cc.cc.lib
httpie
go
go-task
docker
amazon-ecr-credential-helper
jq
nodejs_20
nodePackages.lerna
google-chrome
subfinder
amass
imagemagick
yarn
];
in {
devShells.default = pkgs.mkShell {
packages = commonDeps;
shellHook = ''
# 1. Python & uv Setup
pyenv global system
export pythonEnv=${pythonEnv}
export PATH=$PATH:${pythonEnv}/bin
# Ensure uv uses the Nix-provided Python interpreter
export UV_PYTHON=${pythonEnv}/bin/python
# 2. Service Orchestration
docker compose up --build -d
docker compose ps -a
task dependencies
# 3. AWS & Docker Credential Automation
mkdir -p ~/.docker
echo '{
"credsStore": "ecr-login"
}' > ~/.docker/config.json
echo "Docker config set to use docker-credential-ecr-login"
'';
LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath [
pkgs.stdenv.cc.cc.lib
];
};
});
}
声明式环境
在 commonDeps 中,我列出了从编译器(gcc)到像 amazon-ecr-credential-helper 这样的专用工具的所有内容。有人加入项目时,无需手动 安装 这些。Nix 会获取并链接它们到一个隔离的环境中,保持宿主系统干净,项目可移植。
我使用 uv 是因为它速度惊人且能无缝集成现有的 Python 环境。通过在 shellHook 中设置 export UV_PYTHON=${pythonEnv}/bin/python,我让 uv 使用 Nix 管理的确切 Python 可执行文件,从而确保包管理器与操作系统层面的依赖完全一致。
为什么 Nix 成为项目管理器
- 自动化基础设施 – 我一进入 shell,
docker compose up就会运行。数据库和本地服务在我敲下第一行代码之前就已准备好。 - 自动化配置 –
shellHook会自动写入~/.docker/config.json,从而可以在不手动执行aws ecr get-login-password步骤的情况下推送/拉取 AWS ECR。 - 任务执行 – 运行
task dependencies会在 shell 打开时检查并验证子依赖(例如npm install或go mod download)。
激活设置
要激活整个环境,我运行:
nix --extra-experimental-features 'nix-command flakes' develop --impure --command zsh
--extra-experimental-features 'nix-command flakes'– 启用此设置所需的现代 Nix Flake 命令。--impure– 允许shellHook与外部世界交互(例如你的主目录下的~/.docker和系统 Docker 套接字)。--command zsh– 直接进入我偏好的 shell,并已加载完整环境。
结论
Nix 从根本上改变了我处理项目设置的方式。与其使用包含数十个容易出错的手动安装步骤的冗长 README.md,我只提供一个 flake.nix,它定义了项目的整个环境。这样更快、更安全,并且 100 % 可复现。如果它对我有效,对你也会有效。