mirror of
https://github.com/ryan4yin/nixos-and-flakes-book.git
synced 2024-11-28 19:14:12 +01:00
187 lines
7.8 KiB
Markdown
187 lines
7.8 KiB
Markdown
|
# `flake.nix` Configuration Explained {#flake-nix-configuration-explained}
|
||
|
|
||
|
Above, we created a `flake.nix` file to manage system configurations, but you might still
|
||
|
be unclear about its structure. Let's explain the content of this file in detail.
|
||
|
|
||
|
## 1. Flake Inputs
|
||
|
|
||
|
First, let's look at the `inputs` attribute. It is an attribute set that defines all the
|
||
|
dependencies of this flake. These dependencies will be passed as arguments to the
|
||
|
`outputs` function after they are fetched:
|
||
|
|
||
|
```nix{2-5,7}
|
||
|
{
|
||
|
inputs = {
|
||
|
# NixOS official package source, using the nixos-23.11 branch here
|
||
|
nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.11";
|
||
|
};
|
||
|
|
||
|
outputs = { self, nixpkgs, ... }@inputs: {
|
||
|
# Omitting previous configurations......
|
||
|
};
|
||
|
}
|
||
|
```
|
||
|
|
||
|
Dependencies in `inputs` has many types and definitions. It can be another flake, a
|
||
|
regular Git repository, or a local path. The section
|
||
|
[Other Usage of Flakes - Flake Inputs](../other-usage-of-flakes/inputs.md) describes
|
||
|
common types of dependencies and their definitions in detail.
|
||
|
|
||
|
Here we only define a dependency named `nixpkgs`, which is the most common way to
|
||
|
reference in a flake, i.e., `github:owner/name/reference`. The `reference` here can be a
|
||
|
branch name, commit-id, or tag.
|
||
|
|
||
|
After `nixpkgs` is defined in `inputs`, you can use it in the parameters of the subsequent
|
||
|
`outputs` function, which is exactly what our example does.
|
||
|
|
||
|
## 2. Flake Outputs
|
||
|
|
||
|
Now let's look at `outputs`. It is a function that takes the dependencies from `inputs` as
|
||
|
its parameters, and its return value is an attribute set, which represents the build
|
||
|
results of the flake:
|
||
|
|
||
|
```nix{11-19}
|
||
|
{
|
||
|
description = "A simple NixOS flake";
|
||
|
|
||
|
inputs = {
|
||
|
# NixOS official package source, here using the nixos-23.11 branch
|
||
|
nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.11";
|
||
|
};
|
||
|
|
||
|
outputs = { self, nixpkgs, ... }@inputs: {
|
||
|
# The host with the hostname `my-nixos` will use this configuration
|
||
|
nixosConfigurations.my-nixos = nixpkgs.lib.nixosSystem {
|
||
|
system = "x86_64-linux";
|
||
|
modules = [
|
||
|
./configuration.nix
|
||
|
];
|
||
|
};
|
||
|
};
|
||
|
}
|
||
|
```
|
||
|
|
||
|
Flakes can have various purposes and can have different types of outputs. The section
|
||
|
[Flake Outputs](../other-usage-of-flakes/outputs.md) provides a more detailed
|
||
|
introduction. Here, we are only using the `nixosConfigurations` type of outputs, which is
|
||
|
used to configure NixOS systems.
|
||
|
|
||
|
When we run the `sudo nixos-rebuild switch` command, it looks for the
|
||
|
`nixosConfigurations.my-nixos` attribute (where `my-nixos` will be the hostname of your
|
||
|
current system) in the attribute set returned by the `outputs` function of
|
||
|
`/etc/nixos/flake.nix` and uses the definition there to configure your NixOS system.
|
||
|
|
||
|
Actually, we can also customize the location of the flake and the name of the NixOS
|
||
|
configuration instead of using the defaults. This can be done by adding the `--flake`
|
||
|
parameter to the `nixos-rebuild` command. Here's an example:
|
||
|
|
||
|
```nix
|
||
|
sudo nixos-rebuild switch --flake /path/to/your/flake#your-hostname
|
||
|
```
|
||
|
|
||
|
A brief explanation of the `--flake /path/to/your/flake#your-hostname` parameter:
|
||
|
|
||
|
1. `/path/to/your/flake` is the location of the target flake. The default path is
|
||
|
`/etc/nixos/`.
|
||
|
2. `#` is a separator, and `your-hostname` is the name of the NixOS configuration.
|
||
|
`nixos-rebuild` will default to using the hostname of your current system as the
|
||
|
configuration name to look for.
|
||
|
|
||
|
You can even directly reference a remote GitHub repository as your flake source, for
|
||
|
example:
|
||
|
|
||
|
```nix
|
||
|
sudo nixos-rebuild switch --flake github:owner/repo#your-hostname
|
||
|
```
|
||
|
|
||
|
## 3. The Special Parameter `self` of the `outputs` Function {#special-parameter-self-of-outputs-function}
|
||
|
|
||
|
Although we have not mentioned it before, all the example code in the previous sections
|
||
|
has one more special parameter in the `outputs` function, and we will briefly introduce
|
||
|
its purpose here.
|
||
|
|
||
|
The description of it in the [nix flake - Nix Manual] is:
|
||
|
|
||
|
> The special input named `self` refers to the outputs and source tree of this flake.
|
||
|
|
||
|
This means that `self` is the return value of the current flake's `outputs` function and
|
||
|
also the path to the current flake's source code folder (source tree).
|
||
|
|
||
|
We are not using the `self` parameter here, but in some more complex examples (or
|
||
|
configurations you may find online) later, you will see the usage of `self`.
|
||
|
|
||
|
> Note: You might come across some code where people use `self.outputs` to reference the
|
||
|
> outputs of the current flake, which is indeed possible. However, the Nix Manual does not
|
||
|
> provide any explanation for this, and it is considered an internal implementation detail
|
||
|
> of flakes. It is not recommended to use this in your own code!
|
||
|
|
||
|
## 4. Simple Introduction to `nixpkgs.lib.nixosSystem` Function {#simple-introduction-to-nixpkgs-lib-nixos-system}
|
||
|
|
||
|
**A Flake can depend on other Flakes to utilize the features they provide.**
|
||
|
|
||
|
By default, a flake searches for a `flake.nix` file in the root directory of each of its
|
||
|
dependencies (i.e., each item in `inputs`) and lazily evaluates their `outputs` functions.
|
||
|
It then passes the attribute set returned by these functions as arguments to its own
|
||
|
`outputs` function, enabling us to use the features provided by the other flakes within
|
||
|
our current flake.
|
||
|
|
||
|
More precisely, the evaluation of the `outputs` function for each dependency is lazy. This
|
||
|
means that a flake's `outputs` function is only evaluated when it is actually used,
|
||
|
thereby avoiding unnecessary calculations and improving efficiency.
|
||
|
|
||
|
The description above may be a bit confusing, so let's take a look at the process with the
|
||
|
`flake.nix` example used in this section. Our `flake.nix` declares the `inputs.nixpkgs`
|
||
|
dependency, so that [nixpkgs/flake.nix] will be evaluated when we run the
|
||
|
`sudo nixos-rebuild switch` command.
|
||
|
|
||
|
From the source code of the Nixpkgs repository, we can see that its flake outputs
|
||
|
definition includes the `lib` attribute, and in our example, we use the `lib` attribute's
|
||
|
`nixosSystem` function to configure our NixOS system:
|
||
|
|
||
|
```nix{8-13}
|
||
|
{
|
||
|
inputs = {
|
||
|
# NixOS official package source, here using the nixos-23.11 branch
|
||
|
nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.11";
|
||
|
};
|
||
|
|
||
|
outputs = { self, nixpkgs, ... }@inputs: {
|
||
|
nixosConfigurations.my-nixos = nixpkgs.lib.nixosSystem {
|
||
|
system = "x86_64-linux";
|
||
|
modules = [
|
||
|
./configuration.nix
|
||
|
];
|
||
|
};
|
||
|
};
|
||
|
}
|
||
|
```
|
||
|
|
||
|
The attribute set following `nixpkgs.lib.nixosSystem` is the function's parameter. We have
|
||
|
only set two parameters here:
|
||
|
|
||
|
1. `system`: This is straightforward, it's the system architecture parameter.
|
||
|
2. `modules`: This is a list of modules, where the actual NixOS system configuration is
|
||
|
defined. The `/etc/nixos/configuration.nix` configuration file itself is a Nixpkgs
|
||
|
Module, so it can be directly added to the `modules` list for use.
|
||
|
|
||
|
Understanding these basics is sufficient for beginners. Exploring the
|
||
|
`nixpkgs.lib.nixosSystem` function in detail requires a grasp of the Nixpkgs module
|
||
|
system. Readers who have completed the
|
||
|
[Modularizing NixOS Configuration](./modularize-the-configuration.md) section can return
|
||
|
to [nixpkgs/flake.nix] to find the definition of `nixpkgs.lib.nixosSystem`, trace its
|
||
|
source code, and study its implementation.
|
||
|
|
||
|
[nix flake - Nix Manual]:
|
||
|
https://nixos.org/manual/nix/stable/command-ref/new-cli/nix3-flake#flake-inputs
|
||
|
[nixpkgs/flake.nix]: https://github.com/NixOS/nixpkgs/tree/nixos-23.11/flake.nix
|
||
|
[nixpkgs/nixos/lib/eval-config.nix]:
|
||
|
https://github.com/NixOS/nixpkgs/tree/nixos-23.11/nixos/lib/eval-config.nix
|
||
|
[Module System - Nixpkgs]:
|
||
|
https://github.com/NixOS/nixpkgs/blob/23.11/doc/module-system/module-system.chapter.md
|
||
|
[nixpkgs/nixos-23.11/lib/modules.nix - _module.args]:
|
||
|
https://github.com/NixOS/nixpkgs/blob/nixos-23.11/lib/modules.nix#L122-L184
|
||
|
[nixpkgs/nixos-23.11/nixos/doc/manual/development/option-types.section.md#L237-L244]:
|
||
|
https://github.com/NixOS/nixpkgs/blob/nixos-23.11/nixos/doc/manual/development/option-types.section.md?plain=1#L237-L244
|
||
|
|
||
|
|