Overlays
In the previous section, we learned about overriding derivations by pkgs.xxx.override { ... }
or pkgs.xxx.overrideAttrs (finalAttrs: previousAttrs: { ... });
. However, this approach will generate a new derivation and doesn't modify the original derivation in pkgs
instance. If the derivation you want to override is also used by other Nix packages, they will still use the unmodified derivation.
To globally modify derivations in the detault nixpkgs instance, 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, with Flakes feature, to ensure system reproducibility, overlays cannot rely on configurations outside of the Git repository.
When using flake.nix
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:
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:
# ./overlays/default.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 ./overlays/overlay3/default.nix is the same as above:
# `(final: prev: { xxx = prev.xxx.override { ... }; })`
(import ./overlay3)
];
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
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 environment variables. - Overlay 3 is defined in a separate file
./overlays/overlay3/default.nix
.
One example of importing the above configuration as a NixOS module is as follows:
# ./flake.nix
{
inputs = {
# ...
};
outputs = inputs@{ nixpkgs, ... }: {
nixosConfigurations = {
my-nixos = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
./configuration.nix
# import the module that contains overlays
(import ./overlays)
];
};
};
};
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
This is just an example. Please write your own overlays according to your needs.
Multiple nixpkgs Instances with different Overlays
The nixpkgs.overlays = [...];
mentioned above directly modifies the global nixpkgs instance pkgs
. If your overlays make changes to some low-level packages, it might impact other modules. One downside is an increase in local compilation (due to cache invalidation), and there might also be functionality issues with the affected packages.
If you wish to utilize overlays only in a specific location without affecting the default nixpkgs instance, you can instantiate a new nixpkgs instance and apply your overlays to it. We will discuss how to do this in the next section The Ingenious Uses of Multiple nixpkgs Instances.