Nix 实战:用声明式构建系统打造100%可复现的开发环境
Nix in Practice: 100% Reproducible Development Environments with Declarative Builds
| iDev Tech | 2026-08-29T03:24:51
探索 Nix 包管理器和 NixOS 如何通过纯函数式和声明式的方式,彻底解决「在我机器上能跑」的经典问题。
Explore how the Nix package manager and NixOS use purely functional and declarative approaches to permanently solve the classic 'works on my machine' problem.
为什么需要 Nix 每个开发者都遇到过这个问题:「在我机器上能跑」。根本原因在于环境不一致——不同版本的编译器、运行时、系统库在不同机器上产生不同的行为。Docker 部分解决了这个问题,但 Nix 从更根本的层面给出了答案。 Nix 核心理念 纯函数式:每个包的构建输出只取决于其输入(源码+依赖),与系统环境完全隔离 内容寻址:包的存储路径包含其输入的哈希值,不同版本可以共存 声明式:通过 flake.nix 文件声明整个项目的依赖图 原子更新:环境切换是原子操作,可以安全回滚 Nix Flakes 实战 以一个包含 Java 17、Node.js 20 和 PostgreSQL 16 的全栈项目为例:在项目根目录创建 flake.nix 文件,声明所有开发依赖。任何团队成员运行 nix develop 命令后,将获得完全一致的开发环境——精确到每个库的版本和编译选项。 与 Docker 的对比 Nix 和 Docker 解决不同层面的问题。Docker 提供运行时隔离,Nix 提供构建可复现性。最佳实践是两者结合使用:用 Nix 构建确定性的 Docker 镜像,镜像内容完全由 Nix 表达式决定。这样既享受了 Nix 的可复现性,又保留了 Docker 的部署便利性。 2026 年,越来越多的 CI/CD 平台(包括 GitHub Actions 和 GitLab CI)已原生支持 Nix 缓存,使得基于 Nix 的构建流水线在速度和可靠性上都更具竞争力。
Why Nix Every developer has encountered this problem: "it works on my machine." The root cause is environment inconsistency — different versions of compilers, runtimes, and system libraries produce different behaviors on different machines. Docker partially solves this, but Nix provides a more fundamental answer. Nix Core Principles Purely Functional: Each package's build output depends solely on its inputs (source + dependencies), completely isolated from the system environment Content-Addressed: Package storage paths include input hashes, allowing different versions to coexist Declarative: Entire project dependency graphs are declared through flake.nix files Atomic Updates: Environment switches are atomic operations with safe rollback Nix Flakes in Practice Using a full-stack project requiring Java 17, Node.js 20, and PostgreSQL 16 as an example: create a flake.nix file in the project root declaring all development dependencies. When any team member runs the nix develop command, they receive an identical development environment — exact down to every library version and compilation option. Comparison with Docker Nix and Docker solve problems at different levels. Docker provides runtime isolation; Nix provides build reproducibility. The best practice is combining both: use Nix to build deterministic Docker images whose contents are entirely determined by Nix expressions. This way you enjoy Nix's reproducibility while retaining Docker's deployment convenience. In 2026, an increasing number of CI/CD platforms (including GitHub Actions and GitLab CI) natively support Nix caching, making Nix-based build pipelines more competitive in both speed and reliability.