mirror of
https://github.com/ryan4yin/nixos-and-flakes-book.git
synced 2024-12-12 18:00:44 +01:00
162 lines
5.9 KiB
Markdown
162 lines
5.9 KiB
Markdown
# Overlays
|
|
|
|
In the previous section, we learned about overriding derivations using the `override` keyword. However, this approach only affects the local derivation and doesn't modify the original derivation in `pkgs`. To globally modify derivations in `pkgs`, Nix provides a feature called "overlays".
|
|
|
|
In traditional Nix environments, overlays can be configured globally using the `~/.config/nixpkgs/overlays.nix` or `~/.config/nixpkgs/overlays/*.nix` files. However, in Flakes, to ensure system reproducibility, overlays cannot rely on configurations outside of the Git repository.
|
|
|
|
When using Flakes to configure NixOS, both Home Manager and NixOS provide the `nixpkgs.overlays` option to define overlays. You can refer to the following documentation for more details:
|
|
|
|
- [Home Manager docs - `nixpkgs.overlays`](https://nix-community.github.io/home-manager/options.html#opt-nixpkgs.overlays)
|
|
- [Nixpkgs source code - `nixpkgs.overlays`](https://github.com/NixOS/nixpkgs/blob/30d7dd7e7f2cba9c105a6906ae2c9ed419e02f17/nixos/modules/misc/nixpkgs.nix#L169)
|
|
|
|
Let's take a look at an example module that loads overlays. This module can be used as a Home Manager module or a NixOS module, as the definitions are the same:
|
|
|
|
```nix
|
|
{ config, pkgs, lib, ... }:
|
|
|
|
{
|
|
nixpkgs.overlays = [
|
|
# Overlay 1: Use `self` and `super` to express the inheritance relationship
|
|
(self: super: {
|
|
google-chrome = super.google-chrome.override {
|
|
commandLineArgs =
|
|
"--proxy-server='https=127.0.0.1:3128;http=127.0.0.1:3128'";
|
|
};
|
|
})
|
|
|
|
# Overlay 2: Use `final` and `prev` to express the relationship between the new and the old
|
|
(final: prev: {
|
|
steam = prev.steam.override {
|
|
extraPkgs = pkgs: with pkgs; [
|
|
keyutils
|
|
libkrb5
|
|
libpng
|
|
libpulseaudio
|
|
libvorbis
|
|
stdenv.cc.cc.lib
|
|
xorg.libXcursor
|
|
xorg.libXi
|
|
xorg.libXinerama
|
|
xorg.libXScrnSaver
|
|
];
|
|
extraProfile = "export GDK_SCALE=2";
|
|
};
|
|
})
|
|
|
|
# Overlay 3: Define overlays in other files
|
|
# The content of overlay3.nix is the same as above:
|
|
# `(final: prev: { xxx = prev.xxx.override { ... }; })`
|
|
(import ./overlays/overlay3.nix)
|
|
];
|
|
}
|
|
```
|
|
|
|
In the above example, we define three overlays. Overlay 1 modifies the `google-chrome` derivation by adding a command-line argument for a proxy server. Overlay 2 modifies the `steam` derivation by adding extra packages and an environment variable. Overlay 3 is defined in a separate file `overlay3.nix`.
|
|
|
|
You can write your own overlays following this example. Import the configuration as a NixOS module or a Home Manager module, and then deploy it to see the effect.
|
|
|
|
## Modular overlays
|
|
|
|
In the previous example, all overlays were written in a single Nix file, which can become difficult to maintain over time. To address this, we can manage overlays in a modular way.
|
|
|
|
Start by creating an `overlays` folder in your Git repository to store all overlay configurations. Inside this folder, create a `default.nix` file with the following content:
|
|
|
|
```nix
|
|
# import all nix files in the current folder, and execute them with args as parameters
|
|
# The return value is a list of all execution results, which is the list of overlays
|
|
|
|
args:
|
|
# execute and import all overlay files in the current directory with the given args
|
|
builtins.map
|
|
(f: (import (./. + "/${f}") args)) # execute and import the overlay file
|
|
(builtins.filter # find all overlay files in the current directory
|
|
(f: f != "default.nix")
|
|
(builtins.attrNames (builtins.readDir ./.)))
|
|
```
|
|
|
|
The `default.nix` file imports and executes all Nix files in the current folder (excluding `default.nix`) with the provided arguments. It returns a list of all overlay results.
|
|
|
|
Next, write your overlay configurations in the `overlays` folder. For example, you can create `overlays/fcitx5/default.nix` with the following content:
|
|
|
|
```nix
|
|
{ pkgs, config, lib, ... }:
|
|
|
|
(self: super: {
|
|
rime-data = ./rime-data-flypy; # Customized rime-data package
|
|
fcitx5-rime = super.fcitx5-rime.override { rimeDataPkgs = [ ./rime-data-flypy ]; };
|
|
})
|
|
```
|
|
|
|
In the above example, we override the `rime-data` package with a custom version and modify the `fcitx5-rime` derivation to use the custom `rime-data` package.
|
|
|
|
To load all overlays returned by `overlays/default.nix`, add the following parameter to any NixOS module:
|
|
|
|
```nix
|
|
{ config, pkgs, lib, ... } @ args:
|
|
|
|
{
|
|
# ...
|
|
|
|
nixpkgs.overlays = import /path/to/overlays/dir;
|
|
|
|
# ...
|
|
}
|
|
```
|
|
|
|
For instance, you can add it directly in `flake.nix`:
|
|
|
|
```nix
|
|
{
|
|
description = "NixOS configuration of Ryan Yin";
|
|
|
|
# ...
|
|
|
|
inputs = {
|
|
# ...
|
|
};
|
|
|
|
outputs = inputs@{ self, nixpkgs, ... }:
|
|
{
|
|
nixosConfigurations = {
|
|
nixos-test = nixpkgs.lib.nixosSystem {
|
|
system = "x86_64-linux";
|
|
specialArgs = inputs;
|
|
modules = [
|
|
./hosts/nixos-test
|
|
|
|
# add the following inline module definition
|
|
# here, all parameters of modules are passed to overlays
|
|
(args: { nixpkgs.overlays = import ./overlays args; })
|
|
|
|
# ...
|
|
];
|
|
};
|
|
};
|
|
};
|
|
}
|
|
```
|
|
|
|
By using this modular approach, you can conveniently organize and manage your overlays. In this example, the structure of the `overlays` folder would look like this:
|
|
|
|
```txt
|
|
.
|
|
├── flake.lock
|
|
├── flake.nix
|
|
├── home
|
|
├── hosts
|
|
├── modules
|
|
├── ...
|
|
├── overlays
|
|
│ ├── default.nix # return a list of all overlays.
|
|
│ └── fcitx5 # fcitx5 overlay
|
|
│ ├── default.nix
|
|
│ ├── README.md
|
|
│ └── rime-data-flypy # my custom rime-data
|
|
│ └── share
|
|
│ └── rime-data
|
|
│ ├── ...
|
|
└── README.md
|
|
```
|
|
|
|
This modular approach simplifies the management of overlays and allows you to easily add, modify, or remove overlays as needed.
|