feat: polish

This commit is contained in:
Ryan Yin 2023-06-28 16:53:32 +08:00
parent 4c4920f9fc
commit 42973e6bcc
8 changed files with 92 additions and 101 deletions

View file

@ -1,28 +1,30 @@
## Advanced Topics
After becoming familiar with the NixOS, you can further explore Nix's three manuals and other docs to discover more ways to use it:
Once you're familiar with NixOS, you can explore Nix's three manuals and other documentation to discover more ways to use it:
- [Nix Reference Manual](https://nixos.org/manual/nix/stable/package-management/profiles.html): A guide to the Nix package manager, which mainly covers the design of the package manager and instructions for using it from the command line.
- [Nix Reference Manual](https://nixos.org/manual/nix/stable/package-management/profiles.html): A guide to the Nix package manager, which covers the design of the package manager and instructions for using it from the command line.
- [nixpkgs Manual](https://nixos.org/manual/nixpkgs/unstable/): A manual that introduces parameters of Nixpkgs, how to use, modify, and package Nix packages.
- [NixOS Manual](https://nixos.org/manual/nixos/unstable/): A user manual for NixOS, mainly including configuration instructions for system-level components such as Wayland/X11 and GPU.
- [NixOS Manual](https://nixos.org/manual/nixos/unstable/): A user manual for NixOS, which includes configuration instructions for system-level components such as Wayland/X11 and GPU.
- [nix-pills](https://nixos.org/guides/nix-pills): Nix Pills provides an in-depth explanation of how to use Nix to build software packages. It is written in a clear and understandable way and is worth reading, as it is also sufficiently in-depth.
After becoming familiar with Flakes, you may want to try some advanced techniques. Here are some popular community projects to try:
GitHub Copilot: Here's an optimized version of the text:
- [flake-parts](https://github.com/hercules-ci/flake-parts): Simplify the writing and maintenance of configuration through the Module module system.
- [flake-utils-plus](https://github.com/gytis-ivaskevicius/flake-utils-plus): A third-party package for simplifying Flake configuration, which is apparently more powerful.
- [digga][digga]: A large and comprehensive Flake template that combines the functionality of various useful Nix toolkits, but has a complex structure and requires some experience to navigate.
Once you're familiar with Flakes, you may want to explore some advanced techniques. Here are some popular community projects to try out:
- [flake-parts](https://github.com/hercules-ci/flake-parts): This project simplifies the writing and maintenance of configuration through the Module module system.
- [flake-utils-plus](https://github.com/gytis-ivaskevicius/flake-utils-plus): A third-party package that simplifies Flake configuration and is known to be more powerful.
- [digga][digga]: A comprehensive Flake template that combines the functionality of various useful Nix toolkits. However, it has a complex structure and requires some experience to navigate.
- etc.
And many other useful community projects to explore, here are some of them:
There are many other useful community projects to explore. Here are a few examples:
- [nixpak](https://github.com/nixpak/nixpak)
- [nix-output-monitor](https://github.com/maralorn/nix-output-monitor)
- [agenix](https://github.com/ryantm/agenix): secrets management
- [colmena](https://github.com/zhaofengli/colmena): NixOS deployment tools
- [nixos-generator](https://github.com/nix-community/nixos-generators): generate iso/qcow2/... from nixos configuration
- [lanzaboote](https://github.com/nix-community/lanzaboote): enable secure boot for NixOS
- [impermanence](https://github.com/nix-community/impermanence): used to make NixOS stateless, to imporve the reproduciability of NixOS system.
- [agenix](https://github.com/ryantm/agenix): A tool for secrets management
- [colmena](https://github.com/zhaofengli/colmena): Tools for NixOS deployment
- [nixos-generator](https://github.com/nix-community/nixos-generators): A tool to generate iso/qcow2/... from NixOS configuration
- [lanzaboote](https://github.com/nix-community/lanzaboote): A tool to enable secure boot for NixOS
- [impermanence](https://github.com/nix-community/impermanence): A tool used to make NixOS stateless and improve the reproducibility of NixOS systems.
- ...
[digga]: https://github.com/divnix/digga

View file

@ -9,15 +9,15 @@
- By changing a few lines of configuration, various components of NixOS can be easily customized. This is because Nix encapsulates all the underlying complex operations in Nix packages and only exports concise and necessary declarative parameters.
- Moreover, this modification is very safe. For example, switching between different desktop environments on NixOS is very simple and clean, you just need to change several lines of the configuration.
- **Rollback**: The system can be restored to any historical state at any time(except the state that is NOT managed by NixOS, such as docker containers, postgresql data, etc...), and NixOS even adds all old versions to the boot options by default to ensure that the system can be rolled back at any time even though it crashes. Therefore, NixOS is also considered one of the most stable Linux Systems.
- **No dependency conflicts**: Because each software package in Nix has a unique hash, its installation path also includes this hash value, so multiple versions can coexist.
- **The community is very active, and there are quite a few third-party projects**. The official package repository, nixpkgs, has many contributors, and many people share their Nix configuration on Github/Gitlab. After browsing through it, the entire ecosystem gives me a sense of excitement in discovering a new continent.
- **No dependency conflicts**: Each software package in Nix has a unique hash, its installation path also includes this hash value, so multiple versions can coexist.
- **Active community and third-party projects**. The official package repository, nixpkgs, has many contributors, and many people share their Nix configuration on Github/Gitlab. After browsing through it, the entire ecosystem gives me a sense of excitement in discovering a new continent.
## Disadvantages
- **High learning curve:**: If you want the system to be completely reproducible and avoid pitfalls caused by improper use, you need to learn about the entire design of Nix and manage the system in a declarative manner. You cannot blindly use `nix-env -i` (which is similar to `apt-get install`).
- **High learning curve:**: To use NixOS effectively and avoid pitfalls caused by improper use, you need to learn about the entire design of Nix and manage the system in a declarative manner. You should not blindly use `nix-env -i` (which is similar to `apt-get install`).
- **Chaotic documentation**: Flakes is still an experimental feature, and there are currently few documents introducing it, Most of the Nix community's documentation only introduces the old cli such as `nix-env`/`nix-channel`. If you want to start learning Nix directly from Flakes, you need to refer to a large number of old documents and extract what you need from them. In addition, some of Nix's current core functions are not well-documented (such as `imports` and Nix Module System), to figure out what it does, it is best to look at the source code...
- **Relatively high disk space usage**: To ensure that the system can be rolled back at any time, Nix preserves all historical environments by default, which can take up a lot of disk space. It can be a problem, especially on some resource-constrained Virtual Machines.
- **Error messages may be obscure**: Sometimes you may come across some strange error messages and don't understand what's going on.
- **Relatively high disk space usage**: To ensure that the system can be rolled back at any time, Nix preserves all historical environments by default, which can take up a lot of disk space. This can be a problem, especially on some resource-constrained Virtual Machines.
- **Obscure error messages**: Sometimes you may come across some strange error messages and not understand what's going on.
`--show- Trace` may throw you a stack of errors that are of little help.
## Summary

View file

@ -1,8 +1,8 @@
## Introduction to Nix & NixOS
Nix package manager is a declarative configuration management tool. Users need to declare the expected system state in some configuration, and Nix is responsible for achieving that goal.
Nix is a declarative package manager, that allows users to declare the expected system state in some configuration files, and Nix is responsible for achieving that goal.
> To put it simply, "declarative configuration" means that users only need to declare the result they want. For example, you declare that you want to replace the i3 window manager with sway, then Nix will help you achieve the goal. You don't need to worry about the underlying details (such as which packages sway needs to install, which i3-related packages need to be uninstalled, which system configuration or environment variables need to be adjusted for sway, what adjustments need to be made to the Sway parameters if an Nvidia graphics card is used, etc.), Nix will automatically handle these details for the user(prerequisite: if the nix packages related to sway & i3 are designed properly.).
> In simple terms, "declarative configuration" means that users only need to declare the result they want. For example, you declare that you want to replace the i3 window manager with sway, then Nix will help you achieve the goal. You don't need to worry about the underlying details (such as which packages sway needs to install, which i3-related packages need to be uninstalled, which system configuration or environment variables need to be adjusted for sway, what adjustments need to be made to the Sway parameters if an Nvidia graphics card is used, etc.), Nix will automatically handle these details for the user(prerequisite: if the nix packages related to sway & i3 are designed properly.).
NixOS, the Linux distribution built on top of the Nix package manager, can be simply described as "OS as Code", which describes the entire operating system's state using declarative Nix configuration files.
@ -27,6 +27,6 @@ So I switched to NixOS.
I am quite satisfied with NixOS, even more than expected.
The most amazing thing is, now I can restore the entire i3 environment and my commonly used packages on a fresh NixOS host with just one command, that's really fantastic!
The rollback capability of NixOS gave me a lot of confidence - I no longer fear breaking the system anymore. I even tried a lot of new things on NixOS, such as hyprland compositor. (On EndeavourOS before, I wouldn't have dared to play with such new compositors - it would have been a big hassle if something went wrong with the system and I need to fix it manually through various tricks.)
The rollback capability of NixOS gave me a lot of confidence - I no longer fear breaking the system anymore. I even tried a lot of new things on NixOS, such as hyprland compositor. (I wouldn't have dared to play with such new compositors on EndeavourOS - it would have been a big hassle if something went wrong with the system and I need to fix it manually through various tricks.)
So that's why I chose NixOS.
That's why I chose NixOS.

View file

@ -1,13 +1,10 @@
## Installation
Nix can be installed in multiple ways:
1. Install on macOS/Linux/WSL as a package manager.
2. Install NixOS, it's a Linux distribution that uses Nix to manage the entire system environment.
1. As a package manager on macOS/Linux/WSL.
2. Manage the entire system environment on NixOS, it's a Linux distribution that uses Nix to manage the system.
This book aims to introduce the usage of NixOS & Flakes, so we just skip the content related only to Nix here.
This book focuses on introducing the usage of NixOS & Flakes, so we will skip the content related only to Nix.
The installation process of NixOS is simple, and I won't go into details here.
Please just go to the official download site to see more details: <https://nixos.org/download.html>
The installation process of NixOS is simple, and we won't go into details here. Please visit the official download site for more information: <https://nixos.org/download.html>.

View file

@ -2,22 +2,19 @@
After learning the basics of the Nix language, we can start using it to configure our NixOS. The default configuration for NixOS is located at `/etc/nixos/configuration.nix`, which contains all the declarative configuration for the system, such as time zone, language, keyboard layout, network, users, file system, boot options, etc.
If we want to modify the system state in a reproducible way (**which is also the most recommended way**), we need to manually edit `/etc/nixos/configuration.nix`, and then execute `sudo nixos-rebuild switch` to apply the modified configuration, it will generate a new system environment based on the configuration file we modified, sets the new environment as the default one, and also preserves & added the previous environment into the boot options of grub/sytemd-boot. This ensures we can always roll back to the old environment(even if the new environment fails to start).
To modify the system state in a reproducible way (**which is the most recommended way**), we need to manually edit `/etc/nixos/configuration.nix`, and then execute `sudo nixos-rebuild switch` to apply the modified configuration. This generates a new system environment based on the modified configuration file, sets the new environment as the default one, and preserves the previous environment in the boot options of grub/systemd-boot. This ensures that we can always roll back to the old environment (even if the new environment fails to start).
`/etc/nixos/configuration.nix` is the classic method to configure NixOS, which relies on data sources configured by `nix-channel` and has no version-locking mechanism, making it difficult to ensure the reproducibility of the system. **A better approach is to use Flakes**, which can ensure the reproducibility of the system and make it easy to manage the configuration.
`/etc/nixos/configuration.nix` is the classic method to configure NixOS, which relies on data sources configured by `nix-channel` and has no version-locking mechanism, making it difficult to ensure the reproducibility of the system. **A better approach is to use Flakes**, which ensures the reproducibility of the system and makes it easy to manage the configuration.
Now first, let's learn how to manage NixOS through the classic method, `/etc/nixos/configuration.nix`, and then migrate to the more advanced Flakes.
Now, let's learn how to manage NixOS through the classic method, `/etc/nixos/configuration.nix`, and then migrate to the more advanced Flakes.
## Configuring the system using `/etc/nixos/configuration.nix`
As I mentioned earlier, this is the classic method to configured NixOS, and also the default method currently used by NixOS. It relies on data sources configured by `nix-channel` and has no version-locking mechanism, making it difficult to ensure the reproducibility of the system.
This is the classic method to configure NixOS, and also the default method currently used by NixOS. It relies on data sources configured by `nix-channel` and has no version-locking mechanism, making it difficult to ensure the reproducibility of the system.
For example, to enable ssh and add a user `ryan`, simply add the following content into `/etc/nixos/configuration.nix`:
```nix
# Edit this configuration file to define what should be installed on
# your system. Help is available in the configuration.nix(5) man page
# and in the NixOS manual (accessible by running 'nixos-help').
{ config, pkgs, ... }:
{
@ -58,7 +55,7 @@ For example, to enable ssh and add a user `ryan`, simply add the following conte
In this configuration, we declared that we want to enable the openssh service, add an ssh public key for the user ryan, and disable password login.
Now, let's run `sudo nixos-rebuild switch` to deploy the modified configuration, and then we can login to the system using ssh with the ssh keys we configured.
Now, run `sudo nixos-rebuild switch` to deploy the modified configuration. After that, you can log in to the system using ssh with the ssh keys you configured.
Any reproducible changes to the system can be made by modifying `/etc/nixos/configuration.nix` and deploying the changes by running `sudo nixos-rebuild switch`.

View file

@ -10,28 +10,28 @@ The benefits of Flakes are obvious, and the entire NixOS community likes it very
:warning: But **Flakes is still an experimental feature**, there are still some problems with it, so it is likely to introduce some breaking changes in the process of stablizing it, and its uncertain how greatly the breaking changes will be.
Overall, I still recommend everyone to use Flakes, this book is also written around NixOS and Flakes after all, but please be prepared for the problems that may be caused by the upcomming breaking changes.
Overall, I stll recommend using Flakes, as this book is written around NixOS and Flakes. However, please be prepared for potential problems caused by upcoming breaking changes.
## Nix Flakes and the classic Nix
## Nix Flakes and Classic Nix
As `nix-command` & `flakes` are still experimental features, the official documentation does not cover them in detail, and the community's documentation about them is also very scattered.
However, from the perspective of reproducibility and ease of management and maintenance, the classic Nix package structure and cli are no longer recommended for use.
So I will not introduce the usage of the classic Nix. It's recommended that beginners just start with `nix-command` & `flakes` and ignore all the contents about the classic Nix.
As `nix-command` and `flakes` are still experimental features, the official documentation does not cover them in detail, and the community's documentation about them is also scattered. However, from the perspective of reproducibility and ease of management and maintenance, the classic Nix package structure and CLI are no longer recommended for use. Therefore, I will not introduce the usage of the classic Nix. It's recommended that beginners start with `nix-command` and `flakes` and ignore all the contents about the classic Nix.
Here are the classic Nix commands and related concepts that are no longer needed after you enabling `nix-command` and `flakes`, when searching for information, you can safely ignore them:
Here are the classic Nix commands and related concepts that are no longer needed after enabling `nix-command` and `flakes`. When searching for information, you can safely ignore them:
1. `nix-channel`: `nix-channel` is similar to other package management tools such as apt/yum/pacman, managing software package versions through stable/unstable/test channels.
GitHub Copilot: Here's an optimized version of the text:
1. `nix-channel`: `nix-channel` manages software package versions through stable/unstable/test channels, similar to other package management tools such as apt/yum/pacman.
1. In Flakes, the functionality of `nix-channel` is completely replaced by `inputs` in `flake.nix`.
2. `nix-env`: `nix-env` is a core command-line tool for classic Nix used to manage software packages in the user environment. It installs packages from the data sources added by `nix-channel`, so the installed package's version are influenced by the channel. Packages installed with `nix-env` are not automatically recorded in Nix's declarative configuration and are entirely outside of its control, making them difficult to reproduce on other machines. Therefore, it is not recommended to use this tool.
1. The corresponding command in Flakes is `nix profile`, it's not recommended to use it either.
3. `nix-shell`: `nix-shell` is used to create a temporary shell environment, which is useful for development and testing.
1. This tool is a bit complicated, so it is split into three sub-commands in Flakes: `nix develop`, `nix shell` and `nix run`.
2. We will introduce these three commands in detail in the "Development" chapter.
4. `nix-build`: `nix-build` is used to build Nix packages, and it places the build results in `/nix/store`, but it does not record them in Nix's declarative configuration.
2. `nix-env`: `nix-env` is a core command-line tool for classic Nix used to manage software packages in the user environment.
1. It installs packages from the data sources added by `nix-channel`, so the installed package's version is influenced by the channel. Packages installed with `nix-env` are not automatically recorded in Nix's declarative configuration and are entirely outside of its control, making them difficult to reproduce on other machines. Therefore, it is not recommended to use this tool.
2. The corresponding command in Flakes is `nix profile`, which is also not recommended for use.
3. `nix-shell`: `nix-shell` creates a temporary shell environment, which is useful for development and testing.
1. In Flakes, this tool is split into three sub-commands: `nix develop`, `nix shell`, and `nix run`. We will introduce these three commands in detail in the "Development" chapter.
4. `nix-build`: `nix-build` builds Nix packages and places the build results in `/nix/store`, but it does not record them in Nix's declarative configuration.
1. In Flakes, `nix-build` is replaced by `nix build`.
5. ...
> maybe `nix-env -qa` is still useful some times, which returns all packages installed in the System.
> NOTE: `nix-env -qa` may still be useful sometimes, as it returns all packages installed in the system.
## When will flakes stablized {#when-will-flakes-stablized}

View file

@ -1,6 +1,6 @@
## Modularize your NixOS configuration
## Modularize Your NixOS Configuration
At this point, the skeleton of the entire system is basically configured. The current configuration structure in `/etc/nixos` should be as follows:
At this point, the skeleton of the entire system is configured. The current configuration structure in `/etc/nixos` should be:
```
$ tree
@ -11,27 +11,27 @@ $ tree
└── configuration.nix
```
The functions of these four files are explained below:
The functions of these four files are:
- `flake.lock`: An automatically generated version-lock file, which records all input sources, hash values, and version numbers of the entire flake to ensure that the system is reproducible.
- `flake.nix`: The entry file, which will be recognized and deployed when executing `sudo nixos-rebuild switch`.
- `flake.lock`: An automatically generated version-lock file that records all input sources, hash values, and version numbers of the entire flake to ensure reproducibility.
- `flake.nix`: The entry file that will be recognized and deployed when executing `sudo nixos-rebuild switch`.
- See [Flakes - NixOS Wiki](https://nixos.wiki/wiki/Flakes) for all options of flake.nix.
- `configuration.nix`: Imported as a nix module in flake.nix, all system-level configuration are currently written here.
- `configuration.nix`: Imported as a Nix module in flake.nix, all system-level configuration is currently written here.
- See [Configuration - NixOS Manual](https://nixos.org/manual/nixos/unstable/index.html#ch-configuration) for all options of configuration.nix.
- `home.nix`: Imported by home-manager as the configuration of the user `ryan` in flake.nix, that is, it contains all the configuration of `ryan`, and is responsible for managing `ryan`'s home folder.
- See [Appendix A. Configuration Options - home Manager](https://nix-community.github.io/home-manager/options.html) for all options of home.nix.
- `home.nix`: Imported by Home-Manager as the configuration of the user `ryan` in flake.nix, containing all of `ryan`'s configuration and managing `ryan`'s home folder.
- See [Appendix A. Configuration Options - Home-Manager](https://nix-community.github.io/home-manager/options.html) for all options of home.nix.
By modifying these files, you can change the status of the system and the home directory declaratively.
By modifying these files, you can declaratively change the system and home directory status.
As the configuration increases, it will be difficult to maintain the configuration by relying solely on `configuration.nix` and `home.nix`. Therefore, a better solution is to use the nix module system to split the configuration into multiple modules and write them in a classified manner.
As the configuration increases, it becomes difficult to maintain the configuration by relying solely on `configuration.nix` and `home.nix`. Therefore, a better solution is to use the Nix module system to split the configuration into multiple modules and write them in a classified manner.
Nix module system provide a paramter, `imports`, which accept a list of `.nix` files, and merge all the configuration defined in these files into the current nix module. Note that the word used here is "**merge**", which means that `imports` will **NOT** simply overwrite the duplicate configuration, but handle them more reasonably. For example, if I define `program.packages = [...]` in multiple modules, then `imports` will merge all `program.packages` defined in all nix modules into one list. Not only lists can be merged correctly, but attribute sets can also be merged correctly. The specific behavior can be explored by yourself.
The Nix module system provides a parameter, `imports`, which accepts a list of `.nix` files and merges all the configuration defined in these files into the current Nix module. Note that `imports` will not simply overwrite duplicate configuration, but handle it more reasonably. For example, if `program.packages = [...]` is defined in multiple modules, then `imports` will merge all `program.packages` defined in all Nix modules into one list. Attribute sets can also be merged correctly. The specific behavior can be explored by yourself.
> I only found a description of `imports` in [nixpkgs-unstable official manual - evalModules parameters](https://nixos.org/manual/nixpkgs/unstable/#module-system-lib-evalModules-parameters): `A list of modules. These are merged together to form the final configuration.`, it's a bit ambiguous...
> I only found a description of `imports` in [Nixpkgs-Unstable Official Manual - evalModules Parameters](https://nixos.org/manual/nixpkgs/unstable/#module-system-lib-evalModules-parameters): `A list of modules. These are merged together to form the final configuration.`, it's a bit ambiguous...
With the help of `imports`, we can split `home.nix` and `configuration.nix` into multiple nix modules defined in diffrent `.nix` files.
With the help of `imports`, we can split `home.nix` and `configuration.nix` into multiple Nix modules defined in different `.nix` files.
Use [ryan4yin/nix-config/v0.0.2](https://github.com/ryan4yin/nix-config/tree/v0.0.2) as an example, which is the configuration of my previous NixOS system with i3 window manager. The structure of it is as follows:
For example, [ryan4yin/nix-config/v0.0.2](https://github.com/ryan4yin/nix-config/tree/v0.0.2) is the configuration of my previous NixOS system with i3 window manager. Its structure is:
```shell
├── flake.lock
@ -88,13 +88,13 @@ Use [ryan4yin/nix-config/v0.0.2](https://github.com/ryan4yin/nix-config/tree/v0.
For more details, see [ryan4yin/nix-config/v0.0.2](https://github.com/ryan4yin/nix-config/tree/v0.0.2).
## `lib.mkOverride`, `lib.mkDefault` and `lib.mkForce`
## `lib.mkOverride`, `lib.mkDefault`, and `lib.mkForce`
You may found some people use `lib.mkDefault` `lib.mkForce` to define values in Nix files, as their names suggest, `lib.mkDefault` and `lib.mkForce` are used to set default values or force values of options.
Some people use `lib.mkDefault` and `lib.mkForce` to define values in Nix files. As their names suggest, `lib.mkDefault` and `lib.mkForce` are used to set default values or force values of options.
You can read the source code of `lib.mkDefault` and `lib.mkForce` to understand them by running `nix repl -f '<nixpkgs>'` and then enter `:e lib.mkDefault`(To learn the basic usage of `nix repl`, just type `:?` to see the help information).
You can read the source code of `lib.mkDefault` and `lib.mkForce` by running `nix repl -f '<nixpkgs>'` and then entering `:e lib.mkDefault`. To learn the basic usage of `nix repl`, type `:?` to see the help information.
Its source code is as follows:
Here's the source code:
```nix
# ......
@ -113,16 +113,13 @@ Its source code is as follows:
# ......
```
So `lib.mkDefault` is used to set default values of options, it has a priority of 1000 internally,
and `lib.mkForce` is used to force values of options, it has a priority of 50 internally.
If you just set a value of an option directly, it will be set with a default priority of 1000(the same as `lib.mkDefault`).
`lib.mkDefault` is used to set default values of options with a priority of 1000 internally, while `lib.mkForce` is used to force values of options with a priority of 50 internally. If you set a value of an option directly, it will be set with a default priority of 1000 (the same as `lib.mkDefault`).
The lower the `priority`'s value is, the higher the actual priority is, so `lib.mkForce` has a higher priority than `lib.mkDefault`.
If you defined multiple values with the same priority, Nix will throw an error.
The lower the `priority` value, the higher the actual priority. Therefore, `lib.mkForce` has a higher priority than `lib.mkDefault`. If you define multiple values with the same priority, Nix will throw an error.
They are useful to modularize the configuration, as you can set default values in a low-level module(base module), and force values in a high-level module.
These functions are useful for modularizing the configuration. You can set default values in a low-level module (base module) and force values in a high-level module.
For example, I defined some default values in <https://github.com/ryan4yin/nix-config/blob/main/modules/nixos/core-server.nix#L30>:
As an example, in my configuration <https://github.com/ryan4yin/nix-config/blob/main/modules/nixos/core-server.nix#L30>, I define default values here:
```nix
{ lib, pkgs, ... }:
@ -154,14 +151,13 @@ And for my dekstop machine, I force the values to another value in <https://gith
}
```
## `lib.mkOrder`, `lib.mkBefore` and `lib.mkAfter`
## `lib.mkOrder`, `lib.mkBefore`, and `lib.mkAfter`
`lib.mkBefore` and `lib.mkAfter` are used to set the merge order of **list-type options**, just like `lib.mkDefault` and `lib.mkForce`, they're also useful to modularize the configuration.
`lib.mkBefore` and `lib.mkAfter` are used to set the merge order of **list-type options**. Like `lib.mkDefault` and `lib.mkForce`, they're also useful for modularizing the configuration.
I said before that if you defined multiple values with the same **override priority**, Nix will throw an error.
But with `lib.mkOrder`, `lib.mkBefore` or `lib.mkAfter`, you can define multiple values with the same override priority, they will be merged in the order you defined.
As I mentioned earlier, if you define multiple values with the same **override priority**, Nix will throw an error. However, with `lib.mkOrder`, `lib.mkBefore`, or `lib.mkAfter`, you can define multiple values with the same override priority, and they will be merged in the order you defined.
Let's running `nix repl -f '<nixpkgs>'` and then enter `:e lib.mkBefore` to take a look at its source code(To learn the basic usage of `nix repl`, just type `:?` to see the help information):
To take a look at the source code of `lib.mkBefore`, run `nix repl -f '<nixpkgs>'` and then enter `:e lib.mkBefore`. To learn the basic usage of `nix repl`, type `:?` to see the help information:
```nix
# ......
@ -242,7 +238,7 @@ nix-repl> outputs.nixosConfigurations.nixos-test.config.environment.systemPackag
«derivation /nix/store/qpmpvq5azka70lvamsca4g4sf55j8994-vim-9.0.1441.drv» ]
```
So we can see that the order of `systemPackages` is `git -> curl -> default packages -> vim`, which is the same as the order we defined in `flake.nix`.
As we can see, the order of `systemPackages` is `git -> curl -> default packages -> vim`, which is the same as the order we defined in `flake.nix`.
> Though it's useless to adjust the order of `systemPackages`, it may be helpful at some other places...

View file

@ -2,9 +2,9 @@
### Enabling Flakes Support
Compared to the default configuration approach of NixOS, Flakes provide better reproducibility and a clearer package structure that is easier to maintain. Therefore, it is recommended to manage NixOS with Flakes.
Flakes provide better reproducibility and a clearer package structure that is easier to maintain compared to the default configuration approach of NixOS. Therefore, it's recommended to manage NixOS with Flakes.
However, as Flakes is still an experimental feature currently, it's not enabled by default yet, we need to enable it manually by modifying `/etc/nixos/configuration.nix`, example as follows:
However, as Flakes is still an experimental feature, it's not enabled by default. To enable it, modify `/etc/nixos/configuration.nix` as follows:
```nix
# Edit this configuration file to define what should be installed on
@ -36,13 +36,13 @@ However, as Flakes is still an experimental feature currently, it's not enabled
}
```
Now run `sudo nixos-rebuild switch` to apply the changes, and then you can write the configuration for NixOS with Flakes.
To apply the changes, run `sudo nixos-rebuild switch`. After that, you can write the configuration for NixOS with Flakes.
### Switching System Configuration to `flake.nix`
After enabling `flakes`, `sudo nixos-rebuild switch` will try to read`/etc/nixos/flake.nix` first every time you run it, if not found, it will fallback to `/etc/nixos/configuration.nix`.
After enabling `flakes`, `sudo nixos-rebuild switch` will first try to read `/etc/nixos/flake.nix` every time you run it. If not found, it will fallback to `/etc/nixos/configuration.nix`.
Now to learn how to write a flake, let's take a look at the official flake templates provided by Nix. First, check which templates are available:
To learn how to write a flake, take a look at the official flake templates provided by Nix. To check which templates are available, run:
```bash
nix flake show templates
@ -55,10 +55,9 @@ nix flake init -t templates#full
cat flake.nix
```
After reading this example, let's create a file `/etc/nixos/flake.nix` and copy the content of the example into it.
With `/etc/nixos/flake.nix`, all system modifications will be taken over by Flakes from now on.
After reading the example, create a file `/etc/nixos/flake.nix` and copy the content of the example into it. From now on, all system modifications will be taken over by Flakes with `/etc/nixos/flake.nix`.
The template we copied CAN NOT be used directly, we need to modify it to make it work, an example of `/etc/nixos/flake.nix` is as follows:
Note that the template we copied cannot be used directly. We need to modify it to make it work. Here's an example of `/etc/nixos/flake.nix`:
```nix
{
@ -132,17 +131,17 @@ The template we copied CAN NOT be used directly, we need to modify it to make it
}
```
Here we defined a NixOS system called `nixos-test`, whose configuration file is `./configuration.nix`, which is the classic configuration we modified before, so we can still make use of it.
We defined a NixOS system called `nixos-test` with a configuration file at `./configuration.nix`, which is the classic configuration we modified before. Therefore, we can still make use of it.
Now run `sudo nixos-rebuild switch` to apply the configuration, and no changes will be made to the system, because we imported the old configuration file in `/etc/nixos/flake.nix`, so the actual state we declared remains unchanged.
To apply the configuration, run `sudo nixos-rebuild switch`. No changes will be made to the system because we imported the old configuration file in `/etc/nixos/flake.nix`, so the actual state we declared remains unchanged.
### Manage system software through Flakes
### Manage System Software through Flakes
After the switch, we can now manage the system through Flakes. The most common requirement for managing a system is to install packges. We have seen how to install packages through `environment.systemPackages` before, and these packages are all from the official nixpkgs repository.
After the switch, we can manage the system through Flakes. The most common requirement for managing a system is to install packages. We have seen how to install packages through `environment.systemPackages` before, and these packages are all from the official nixpkgs repository.
Now let's learn how to install packages from other sources through Flakes. This is much more flexible than installing from nixpkgs directly. The most obvious benefit is that you can easily set the version of the software.
Now let's learn how to install packages from other sources through Flakes. This is much more flexible than installing from nixpkgs directly, and the most obvious benefit is that you can easily set the version of the software.
Use [helix](https://github.com/helix-editor/helix) editor as an example, first, we need to add the helix as an input into `flake.nix`:
Let's use [Helix](https://github.com/helix-editor/helix) editor as an example. First, we need to add Helix as an input to `flake.nix`:
```nix
{
@ -198,17 +197,17 @@ Then update `configuration.nix` to install `helix` from the input `helix`:
}
```
Now deploy the changes by `sudo nixos-rebuild switch`, and then we can start the helix editor by `helix` command.
To deploy the changes, run `sudo nixos-rebuild switch`. Then start the Helix editor by running the `helix` command.
### Add Custom Cache Mirror
> You can safely skip this section if you don't need to customize the cache mirror.
> If you don't need to customize the cache mirror, you can safely skip this section.
To speed up package building, Nix provides <https://cache.nixos.org> to cache build results to avoid building every package locally.
To speed up package building, Nix provides <https://cache.nixos.org> to cache build results and avoid building every package locally.
With the NixOS's classic configuration method, other cache sources can be added by using `nix-channel`, but Flakes avoids using any system-level configuration and environment variables to ensure that its build results are not affected by the environment(so the build results are reproducible).
With the classic configuration method in NixOS, other cache sources can be added using `nix-channel`. However, Flakes avoids using any system-level configuration and environment variables to ensure that its build results are not affected by the environment, making the build results reproducible.
Therefore, to customize the cache source, we must add the related configuration in `flake.nix` by using the parameter `nixConfig`. An example is as follows:
Therefore, to customize the cache source, we must add the related configuration in `flake.nix` using the `nixConfig` parameter. Here's an example:
```nix
{