feat: update faq

This commit is contained in:
Ryan Yin 2023-07-08 00:32:56 +08:00
parent 3a9f24ea65
commit 8b0162e859
6 changed files with 116 additions and 37 deletions

View File

@ -4,8 +4,34 @@
The difference lies in the nature of the snapshots. System snapshots created with btrfs/zfs are non-reproducible, meaning they do not include the "knowledge" of how to build the snapshot from scratch and are therefore **unexplainable**.
On the other hand, NixOS configuration is a piece of "knowledge" that can build an identical OS from scratch. It is **explainable** and can be automatically built with just a few simple commands. The NixOS configuration serves as a documentation of all the changes made to your OS and is also used to automatically build the OS itself.
On the other hand, NixOS configuration is a piece of "knowledge" that can build an identical OS from scratch. It is **explainable** and can be automatically built with just a few simple commands. The NixOS configuration serves as documentation of all the changes made to your OS and is also used to automatically build the OS itself.
The NixOS configuration file is like the **source code** of a program. As long as the source code is intact, it is easy to modify, review, or rebuild an identical program. In contrast, system snapshots are like compiled binary programs derived from source code, making it much more difficult to modify or review them. Moreover, snapshots are large in size, making sharing or migrating them more costly compared to source code.
However, this doesn't mean that NixOS eliminates the need for system snapshots. As mentioned in Chapter 1 of this book, NixOS can only guarantee reproducibility for everything declared in the declarative configuration. Other aspects of the system that are not covered by the declarative configuration, such as dynamic data in MySQL/PostgreSQL, user-uploaded files, system logs, videos, music, and images in user home directories, still require system snapshots or other means of backup.
## How does Nix compare to traditional system management tools like Ansible?
Nix is not only used for managing desktop environments but is also widely employed for batch management of cloud servers. The official NixOps from the NixOS community and deploy-rs developed by the community are tools specifically designed for this use case.
When compared to widely used traditional tools like Ansible, Nix has the following main advantages:
1. Nix's declarative configuration shields users from underlying details, allowing them to focus on their core requirements and providing a highly convenient system customization capability. Traditional tools like Ansible require users to handle all implementation details themselves.
1. If you have experience with declarative configuration tools such as Terraform or Kubernetes, you should easily understand this point. The benefits of declarative configuration become more significant as the complexity of requirements increases.
2. Nix declares its target state through declarative configuration, and Nix Flakes locks all dependency hashes, version numbers, data sources, and other information in a version lock file called `flake.lock`. This greatly enhances the reproducibility of the system. In contrast, traditional tools like Ansible have poor reproducibility, which is why Docker is so popular—it provides a **completely consistent runtime environment** at a lower cost than traditional operational tools like Ansible.
## What are the advantages of Nix compared to Docker container technology?
Nix and container technologies like Docker do have overlapping use cases, such as:
1. Many people use Nix to manage development and build environments, as discussed in this book. On the other hand, technologies like [Dev Containers](https://github.com/devcontainers/spec), which build development environments based on containers, are also popular.
2. The DevOps/SRE field is currently dominated by container technologies based on Dockerfiles. Commonly used distributions like Ubuntu/Debian are frequently used within containers, and there are also mature options available for the host machine. In this context, what significant advantages do switching to NixOS offer?
Regarding the first point of "managing the development and build environments," Nix provides a development environment experience that closely resembles working directly on the host machine. This offers several advantages over Dev Containers, as outlined below:
1. Nix does not use namespaces for filesystem and network isolation, allowing easy interaction with the host machine's filesystem (including /dev for external devices) and network environment within the Nix-created development environment. In contrast, containers require various mappings to enable communication between the container and the host machine's filesystem, which can sometimes lead to file permission issues.
2. Due to the absence of strong isolation, Nix development environments have no issues supporting GUI applications. Running GUI programs within this environment is as seamless as running them in the system environment.
In other words, Nix provides a development experience that is closest to the host machine, with no strong isolation. Developers can use familiar development and debugging tools in this environment, and their past development experience can be seamlessly migrated. On the other hand, if Dev Containers are used, developers may encounter various issues related to filesystem communication, network environment, user permissions, and the inability to use GUI debugging tools due to strong isolation.
If we decide to use Nix to manage all development environments, then building Docker containers based on Nix would provide the highest level of consistency. Additionally, adopting a unified technological architecture for all environments significantly reduces infrastructure maintenance costs. This answers the second point mentioned earlier: when managing development environments with Nix as a prerequisite, using NixOS for container base images and cloud servers offers distinct advantages.

View File

@ -1,26 +1,40 @@
# Advantages & Disadvantages of NixOS
## Advantages
# Advantages of NixOS
- **Declarative Configuration and Git Integration**:
- Nix Flakes uses a lock file named `flake.lock` to lock dependencies' versions, ensuring system reproducibility. This concept is borrowed from package managers like npm and cargo.
- Compared to Docker, Nix Flakes provides stronger guarantees for reproducibility of build results. Dockerfile is an imperative configuration without an equivalent of `flake.lock`. Docker's reproducibility relies on sharing the large build result through an image registry like Docker Hub.
- **Highly Convenient System Customization**:
- NixOS allows easy customization of various components by modifying a few lines of configuration. Nix encapsulates complex operations in Nix packages and exposes concise and necessary declarative parameters.
- Customization is also safe. For instance, switching between different desktop environments on NixOS is simple and clean, requiring only a few configuration changes.
- **Rollback Capability**: The system can be restored to any previous state at any time (excluding content not managed by NixOS, such as Docker containers and PostgreSQL data). NixOS even adds all old versions to the boot options by default, ensuring the ability to roll back even in case of system crashes. NixOS is considered one of the most stable Linux systems.
- **No Dependency Conflicts**: Each software package in Nix has a unique hash, and its installation path includes this hash value, enabling coexistence of multiple versions.
- **Active Community and Third-Party Projects**: The official package repository, nixpkgs, has numerous contributors, and many individuals share their Nix configurations on GitHub/GitLab. Exploring this ecosystem is like discovering a new continent, filled with excitement.
- **Declarative Configuration, OS as Code**
- NixOS uses declarative configuration to manage the entire system environment. These configurations can be managed directly with Git, allowing the system to be restored to any historical state as long as the configuration files are preserved (provided the desired states are declared in the Nix configuration).
- Nix Flakes further enhance reproducibility by utilizing a `flake.lock` version lock file, which records the data source addresses, hash values, and other relevant information for all dependencies. This design greatly improves Nix's reproducibility and ensures consistent build results. It draws inspiration from package management designs in programming languages like Cargo and NPM.
- **Highly Convenient System Customization Capability**
- With just a few configuration changes, various components of the system can be easily replaced. Nix encapsulates all the underlying complex operations within Nix packages, providing users with a concise set of declarative parameters.
- Modifications are safe and switching between different desktop environments (such as GNOME, KDE, i3, and sway) is straightforward, with minimal pitfalls.
- **Rollback Capability**
- It is possible to roll back to any previous system state, and NixOS even includes all old versions in the boot options by default, ensuring the ability to easily revert changes. Consequently, Nix is regarded as one of the most stable package management approaches.
- **No Dependency Conflict Issues**
- Each software package in Nix has a unique hash, which is incorporated into its installation path, allowing multiple versions to coexist.
## Disadvantages
The community is active, with a diverse range of third-party projects. The official package repository, nixpkgs, has numerous contributors, and many people share their Nix configurations. Exploring the NixOS ecosystem is an exciting experience, akin to discovering a new continent.
- **Steep Learning Curve**: To effectively use NixOS and avoid pitfalls, understanding the entire design of Nix and managing the system declaratively is necessary. Blindly using `nix-env -i` (similar to `apt-get install`) should be avoided.
- **Chaotic Documentation**: Flakes is still an experimental feature, and there is limited documentation available. Most of the Nix community's documentation focuses on the old CLI tools like `nix-env` and `nix-channel`. If starting directly with Flakes, you'll need to refer to a large number of old documents and extract the relevant information. Additionally, some core functions of Nix are poorly documented (e.g., `imports` and Nix Module System), requiring reading the source code for clarity.
- **Relatively High Disk Space Usage**: By default, Nix preserves all historical environments to facilitate rollback, resulting in significant disk space usage. This can be a concern, particularly on resource-constrained virtual machines.
- **Obscure Error Messages**: At times, encountering cryptic error messages can be confusing, leaving you unsure of what went wrong. Using `--show-trace` may provide a stack of errors that offer limited help.
# Disadvantages of NixOS
## Summary
- **High Learning Curve**:
- Achieving complete reproducibility and avoiding pitfalls associated with improper usage requires learning about Nix's entire design and managing the system declaratively, rather than blindly using commands like `nix-env -i` (similar to `apt-get install`).
- **Disorganized Documentation**:
- Currently, Nix Flakes remains an experimental feature, and there is limited documentation specifically focused on it. Most Nix community documentation primarily covers the older `nix-env`/`nix-channel` approach. If you want to start learning directly from Nix Flakes, you need to refer to a significant amount of outdated documentation and extract the relevant information. Additionally, some core features of Nix, such as `imports` and the Nixpkgs Module System, lack detailed official documentation, requiring resorting to source code analysis.
- **Increased Disk Space Usage**:
- To ensure the ability to roll back the system at any time, Nix retains all historical environments by default, resulting in increased disk space usage.
- While this additional space usage may not be a concern on desktop computers, it can become problematic on resource-constrained cloud servers.
- **Obscure Error Messages**:
- In general, error messages are usually clear. However, in some cases, the error messages may not provide specific reasons, and using `--show-trace` can produce a lengthy internal stack trace, making it time-consuming to identify the root cause.
- Two potential reasons for this problem are: (1) Nix is a dynamically-typed language, and various parameters are determined at runtime, and (2) error handling logic in the used flake packages may be inadequate, resulting in unclear error messages. Some obscure errors may not even be traceable through error stacks.
- **More Complex Underlying Implementation**:
- Nix's declarative abstraction introduces additional complexity in the underlying code compared to similar code in traditional imperative tools.
- This complexity increases implementation difficulty and makes it more challenging to make custom modifications at the lower level. However, this burden primarily falls on Nix package maintainers, as regular users have limited exposure to the underlying complexities, reducing their burden.
In general, I believe NixOS is suitable for developers with experience in using Linux and programming, who desire greater control over their systems.
# Summary
If you are new to Linux, I do not recommend starting with NixOS, as it can be a challenging journey.
Overall, I believe that NixOS is suitable for developers with a certain level of Linux usage experience and programming knowledge who desire greater control over their systems.
I do not recommend newcomers without any Linux usage experience to dive directly into NixOS, as it may lead to a frustrating journey.
> If you have more questions about NixOS, you can refer to the last chapter of this book, "FAQ".

View File

@ -2,11 +2,42 @@
## NixOS 的回滚能力与 btrfs / zfs 系统快照回滚有何不同?
区别在于,系统快照的内容是不可复现的,快照内容不包含如何从零构建这个快照的「知识」,是**不可解释的**。
很多使用 Arch Linux / Ubuntu 等常规 Linux 发行版的用户,习惯于使用 btrfs / zfs 等文件系统提供的快照作为「后悔药」,这样系统出了问题能回滚修复。
而本书介绍的 NixOS 也提供了系统状态回滚能力,因此很容易会有这样的疑问:这两种系统回滚功能有何不同?
这里简单解释下,主要区别在于,系统快照的内容是不可复现的,快照内容不包含如何从零构建这个快照的「知识」,是**不可解释的**。
而 NixOS 的配置是一份从零构建出一个一模一样的 OS 的「知识」,是**可解释的**而且可以通过简单几行命令就自动完成这个构建。NixOS 配置本身既是一份记录你的 OS 都做过哪些变更的文档,也是用于自动构建出这个 OS 的配置。
NixOS 的配置文件就像是程序的**源代码**,只要源代码没丢,修改程序、审查程序,或者重新构建出一个一模一样的程序都很简单。
而系统快照就像是源代码编译出来的二进制程序,要对它做修改、审查,都要难得多。而且这个快照很大,分享或者迁移它的成本都要比源代码高得多。
但这并不是说有了 NixOS 就不需要系统快照了,本书第一章就介绍了 NixOS 只能保证在声明式配置中声明的所有内容都是可复现的,而其他未声明式配置覆盖到的系统状态是不受它管辖的。比如 MySQL/PostgreSQL 的动态数据、用户上传的文件、系统日志等等,用户 Home 目录下的视频、音乐、图片等等,这些内容都还是需要系统快照或者其他手段来备份。
但这并不是说有了 NixOS 就不需要系统快照了,本书第一章就介绍了 NixOS 只能保证在声明式配置中声明的所有内容都是可复现的,而其他未声明式配置覆盖到的系统状态是不受它管辖的。比如 MySQL/PostgreSQL 的动态数据、用户上传的文件、系统日志等等,用户 Home 目录下的视频、音乐、图片等等,这些内容都还是需要文件系统快照或者其他手段来备份。
## Nix 与 Ansible 等传统的系统运维工具相比有何优劣?
Nix 不仅可用于管理桌面电脑的环境也有很多人用它批量管理云服务器Nix 官方的 [NixOps](https://github.com/NixOS/nixops) 与社区的 [deploy-rs](https://github.com/serokell/deploy-rs) 都是专为这个场景开发的工具。
Nix 与 Ansible 这类被广泛应用的传统工具比,主要优势就在:
1. Nix 的声明式配置屏蔽了底层细节,使用户只需要关心自己最核心的需求,从而带来了高度便捷的系统自定义能力。而使用 Ansible 这类传统工具,用户需要自己去处理所有的实现细节。
1. 如果你有使用过 terraform/kubernetes 等声明式配置工具,应该很容易理解这一点。需求越是复杂的情况下,声明式配置带来的好处就越大。
2. Nix 通过声明式配置声明了自己的目标状态,而 Nix Flakes 通过一个版本锁文件 `flake.lock` 锁定了所有依赖的 hash 值、版本号、数据源等信息,这极大地提升了系统的可复现能力。而传统的 Ansible 等工具的可复现能力是很差的,这也是为什么 Docker 这么受欢迎的原因——它以较低的代价提供了 Ansible 等传统运维工具提供不了的**完全一致的运行环境**。
## Nix 与 Docker 容器技术相比有何优势?
Nix 与以 Docker 为代表的容器技术的应用场景也存在一定重合,比如说:
1. 有很多人用 Nix 来管理开发编译环境,本书就对此做过介绍。但另一方面也有像 [Dev Containers](https://github.com/devcontainers/spec) 这种基于容器搭建开发环境的技术,而且非常流行。
2. 目前整个 DevOps/SRE 领域基本已经是基于 Dockerfile 的容器技术的天下,容器中常用 Ubuntu/Debian 等发行版,宿主机也同样有很多成熟的发行版可选,改用 NixOS 有什么明显的优势呢?
其中第一点「管理开发编译环境」Nix 创建的开发环境体验非常接近直接在宿主机进行开发,这要比 Dev Containers 好很多,举例如下:
1. Nix 不使用名字空间进行文件系统、网络环境等各方面的隔离,在 Nix 创建的开发环境中也可以很方便地与宿主机文件系统(包括 /dev 宿主机外接设备)、网络环境等等进行交互。而容器要通过各种映射才能宿主机文件系统互通,即使这样也可能会遇到一些文件权限问题。
2. 因为没做啥强隔离Nix 开发环境对 GUI 程序的支持也没任何问题,在这个环境中跑个 GUI 程序的体验就跟在系统环境中跑个 GUI 程序没任何区别。
也就是说Nix 能提供最接近宿主机的开发体验,不存在什么强隔离,开发人员能在这个环境中使用各种熟悉的开发调试工具,过往的开发经验基本都能无痛迁移过来。
而如果使用 Dev Containers那开发人员很可能会遭遇强隔离导致的各种文件系统不互通、网络环境问题、用户权限问题、无法使用 GUI 调试工具等等各种毛病。
而如果我们决定了使用 Nix 来管理所有的开发环境,那么在构建 Docker 容器时也基于 Nix 去构建,显然能提供最强的一致性,同时所有环境都统一了技术架构,这也能明显降低整个基础设施的维护成本。
这就回答了前面提到的第二点,在使用 Nix 管理开发环境的前提下,容器基础镜像与云服务器都使用 NixOS 会存在明显的优势。

View File

@ -2,30 +2,38 @@
## 优点 {#advantages}
- 声明式配置OS as Code可以直接用 Git 管理配置
- NixOS 使用声明式配置来管理整个系统环境,只要你的配置文件不丢,系统就可以随时还原到任一历史状态(前面提过了,只有在 Nix 配置文件中声明了的状态才可被 NixOS 还原)。
- 为了提升系统的可复现能力Nix Flakes 还使用了 `flake.lock` 作为版本锁文件它记录了所有相关数据的数据源地址、hash 值。这个设计实际是从 cargo/npm 等一些编程语言的包管理设计中借鉴来的。
- 与 Docker 相比Dockerfile 实际是命令式的配置而且也不存在版本锁这样的东西Docker 容器环境的可复现实际依赖于直接通过 Docker Hub 分享构建结果Docker 镜像),这可比 Dockerfile 本身大多了。
- 高度便捷的系统自定义能力
- **声明式配置OS as Code**
- NixOS 使用声明式配置来管理整个系统环境,可以直接用 Git 管理这些配置,只要你的配置文件不丢,系统就可以随时还原到任一历史状态(前面提过了,只有在 Nix 配置文件中声明了的状态才可被 NixOS 还原)。
- Nix Flakes 还使用了 `flake.lock` 作为版本锁文件它记录了所有相关数据的数据源地址、hash 值,这极大地提升了 Nix 的可复现能力(或者说增强了构建结果的一致性,这个设计实际是从 cargo/npm 等一些编程语言的包管理设计中借鉴来的)。
- **高度便捷的系统自定义能力**
- 通过改几行配置,就可以简单地更换系统的各种组件。这是因为 Nix 将底层的复杂操作全部封装在了 Nix 软件包中,只给用户提供了简洁且必要的声明式参数。
- 而且这种修改非常安全,你可以很方便地来回切换各种桌面环境(比如 gnome/kde/i3/sway几乎不会遇到坑。
- 可回滚
- **可回滚**
- 可以随时回滚到任一历史环境NixOS 甚至默认将所有旧版本都加入到了启动项,确保系统滚挂了也能随时回退。所以 Nix 也被认为是最稳定的包管理方式。
- 没有依赖冲突问题
- **没有依赖冲突问题**
- 因为 Nix 中每个软件包都拥有唯一的 hash其安装路径中也会包含这个 hash 值,因此可以多版本共存。
- 社区很活跃,第三方项目也挺丰富,官方包仓库 nixpkgs 贡献者众多,也有很多人分享自己的 Nix 配置,一遍浏览下来,整个生态给我一种发现新大陆的兴奋感。
## 缺点 {#disadvantages}
- 学习成本高: 如果你希望系统完全可复现,并且避免各种不当使用导致的坑,那就需要学习了解 Nix 的整个设计,并以声明式的方式管理系统,不能无脑 `nix-env -i`(这类似 `apt-get install`)。
- 文档混乱: 首先 Nix Flakes 目前仍然是实验性特性,介绍它本身的文档目前比较匮乏, Nix 社区绝大多数文档都只介绍了旧的 `nix-env`/`nix-channel`,想直接从 Nix Flakes 开始学习的话,需要参考大量旧文档,从中提取出自己需要的内容。另外一些 Nix 当前的核心功能,官方文档都语焉不详(比如 `imports` 跟 Nixpkgs Module System想搞明白基本只能看源码了...
- 比较吃硬盘空间: 为了保证系统可以随时回退nix 默认总是保留所有历史环境,这非常吃硬盘空间。
- 这在桌面电脑上可能不是啥事,但是在资源受限的云服务器上可能会是个问题。
- 报错信息比较隐晦: 一般的报错提示还是比较清楚的,但是遇到好几次依赖版本有问题或者传参错误提示不出原因,`--show-trace` 直接输出一堆的内部堆栈,都花了很长时间才定位到,通过升级依赖版本或者修正参数后问题解决。
- **学习成本高**:
- 如果你希望系统完全可复现,并且避免各种不当使用导致的坑,那就需要学习了解 Nix 的整个设计,并以声明式的方式管理系统,不能无脑 `nix-env -i`(这类似 `apt-get install`)。
- **文档混乱**:
- 首先 Nix Flakes 目前仍然是实验性特性,介绍它本身的文档目前比较匮乏, Nix 社区绝大多数文档都只介绍了旧的 `nix-env`/`nix-channel`,想直接从 Nix Flakes 开始学习的话,需要参考大量旧文档,从中提取出自己需要的内容。另外一些 Nix 当前的核心功能,官方文档都语焉不详(比如 `imports` 跟 Nixpkgs Module System想搞明白基本只能看源码了...
- **比较吃硬盘空间**:
- 为了保证系统可以随时回退nix 默认总是保留所有历史环境,这会使用更多的硬盘空间。
- 多使用的这这些空间,在桌面电脑上可能不是啥事,但是在资源受限的云服务器上可能会是个问题。
- **报错信息比较隐晦**:
- 一般的报错提示还是比较清楚的,但是遇到好几次依赖版本有问题或者传参错误提示不出原因,`--show-trace` 直接输出一堆的内部堆栈,都花了很长时间才定位到,通过升级依赖版本或者修正参数后问题解决。
- 猜测导致这个问题的原因有两个,一是 Nix 是动态语言,各种参数都是运行时才确定类型。二是我用到的 flake 包的错误处理逻辑写得不太好,错误提示不清晰,一些隐晦的错误甚至通过错误堆栈也定位不到原因。
- **底层实现更复杂**
- Nix 多做了一层声明式的抽象带来了诸多好处,而其代价就是底层的代码实现会比传统的命令式工具中的同类代码更复杂。
- 这导致实现难度更高,对底层做些修改也会更麻烦。不过这个问题带来的负担主要是在 Nix 软件包的维护者身上,普通用户接触底层比较少,负担也就小很多。
## 简单总结下 {#summary}
总的来说,我觉得 NixOS 适合那些有一定 Linux 使用经验与编程经验,并且希望对自己的系统拥有更强掌控力的开发者。
我不推荐没有任何 Linux 使用经验的新人直接上手 NixOS那可能会是一段糟糕的旅程。
> 如果你对 NixOS 还有疑问,可以看看本书的最后一章「常见问题」。

View File

@ -31,4 +31,4 @@ Nix 是一个声明式的软件包管理器,用户需要通过某些配置声
NixOS 的回滚能力给了我非常大的底气,我现在再也不用怕把系统搞挂了(挂了直接回滚就恢复了),于是我又在 NixOS 尝试了许多新鲜玩意儿!
在以前 EndeavourOS 上我肯定是不太敢这么玩的,因为万一要是把系统玩出问题了,就必须手动修复系统状态,那可是相当麻烦。
所以这就是我选择 NixOS 的原因。
这就是我选择 NixOS 的原因。