Skip to content

Flakes 简介

Flakes 实验特性是 Nix 项目的一项重大进展,它引入了一种管理 Nix 表达式之间的依赖关系的策略,提高了 Nix 生态系统中的可复现性、可组合性和可用性。 虽然 Flakes 仍然是一个试验性的功能,但已经被 Nix 社区广泛采用。[1]

Flakes 特性是 Nix 项目中最有意义的变化之一。[2]

简单的说,如果你写过点 JavaScript/Go/Rust/Python,那你应该对 package.json/go.mod/Cargo.toml/pyproject.toml 这些文件不陌生, 在这些编程语言中,这些文件用来描述软件包之间的依赖关系,以及如何构建项目。 同样的,这些编程语言的包管理器还通过 package-lock.json/go.sum/Cargo.lock/poetry.lock 这些文件来锁定依赖的版本,以保证项目的可复现性。

Flakes 就是从上述这类编程语言的包管理器中借鉴了一些思想,以提高 Nix 生态系统中的可复现性、可组合性和可用性。 Flakes 提供了 flake.nix,它类似 package.json,用来描述 Nix 包之间的依赖关系,以及如何构建项目。 同时它还提供了 flake.lock,这是一个类似 package-lock.json 的文件,用来锁定依赖的版本,以保证项目的可复现性。

注意事项 caution

Flakes 带来的好处是显而易见的,整个 NixOS 社区都很喜欢它,目前超过半数的用户已经在大量使用 Flakes[3],因此我们可以相当确定 Flakes 不会被废弃。

⚠️但是 Flakes 目前仍然存在一些问题,因此在将它推向稳定的过程中,Nix 可能会引入一些不兼容的改动,这个改动的大小目前还无法确定。

总的来说,我仍然推荐大家使用 Flakes,毕竟这本书本身也是围绕 NixOS 与 Flakes 编写的,但是也要做好准备——未来可能需要解决一些不兼容变更带来的问题。

Flakes 与传统的 Nix

Nix 于 2020 年推出了 nix-command & flakes 两个新特性,它们提供了全新的命令行工具、标准的 Nix 包结构定义、类似 cargo/npm 的 flake.lock 版本锁文件等等。这两个特性极大地增强了 Nix 的能力,因此虽然至今(2023/5/5)它们仍然是实验性特性,但是已经被 Nix 社区广泛使用。

但由于 nix-command & flakes 仍然是实验性特性,官方文档基本不包含任何介绍它们的内容,同时社区关于 Flakes 的文档也相当分散且不完整。 但是从可复现、易于管理维护的角度讲,旧的 Nix 包结构与命令行工具已经不推荐使用了,因此本书也不会介绍旧的 Nix 包结构与命令行工具的使用方法,也建议新手直接忽略掉这些旧的内容,从 nix-command & flakes 学起。

这里列举下在 nix-command & flakes 中已经不需要用到的旧的 Nix 命令行工具与相关概念,在查找资料时,如果看到它们直接忽略掉就行:

  1. nix-channel: 与 apt/yum/pacman 等其他 Linux 发行版的包管理工具类似,传统的 Nix 也以 stable/unstable/test 等 channel 的形式来管理软件包的版本,可通过此命令修改 Nix 的 channel 信息。
    1. Nix Flakes 在 flake.nix 中通过 inputs 声明依赖包的数据源,通过 flake.lock 锁定依赖版本,完全取代掉了 nix-channel 的功能。
  2. nix-env: 用于管理用户环境的软件包,是传统 Nix 的核心命令行工具。它从 nix-channel 定义的数据源中安装软件包,所以安装的软件包版本受 channel 影响。
    1. 通过 nix-env 安装的包不会被自动记录到 Nix 的声明式配置中,是完全脱离掌控的,无法在其他主机上复现,因此不推荐使用。
    2. 在 Nix Flakes 中对应的命令为 nix profile,我个人也不太推荐直接使用它.
  3. nix-shell: nix-shell 用于创建一个临时的 shell 环境
    1. 这玩意儿可能有点复杂了,因此在 Nix Flakes 中它被拆分成了三个子命令 nix develop, nix shell 以及 nix run,我们会在「构建开发环境」一章详细介绍这三个命令。
  4. nix-build: 用于构建 Nix 包,它会将构建结果放到 /nix/store 路径下,但是不会记录到 Nix 的声明式配置中。
    1. 在 Nix Flakes 中对应的命令为 nix build
  5. nix-collect-garbage: 垃圾回收指令,用于清理 /nix/store 中未被使用的 Store Objects.
    1. 在 Nix Flakes 中对应的命令为 nix store gc --debug.
  6. 以及其他使用地较少的命令,就不一一列出了.
    1. 详细的命令对比列表可以看看 Try to explain nix commands

可能也就 nix-env -qa 这个命令偶尔还会有些用了,它返回当前系统下安装的所有软件包。

Flakes 何时会成为稳定特性?

我深入了解了下 Flakes 现状与未来计划相关的资料,大概有这些:

读完上述内容后,个人猜测,Flakes 可能会在未来一两年内成为稳定特性


  1. Flakes - NixOS Wiki ↩︎

  2. Flakes are such an obviously good thing ↩︎

  3. Draft: 1 year roadmap - NixOS Foundation ↩︎

Released under the MIT License.