-
Notifications
You must be signed in to change notification settings - Fork 8
The flake guide #8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
--- | ||
title: Flakes | ||
--- | ||
|
||
Flakes are one of the most complex and confusing concepts in Nix, especially for beginners. Even though, as dependency lock files, flakes aren't anything new, their use in the context of NixOS, an operating system, adds an unsurprising amount of complexity. | ||
|
||
However, understanding flakes is key for working with Nix systems effectively, and is a lot easier than often thought. | ||
|
||
## What are flakes? | ||
|
||
Flakes are an experimental feature of Nix, but are widely used among the community. It that adds two new important files, the `flake.nix`, an entry-point file for your config, and `flake.lock`, an autogenerated lockfile, based on your `flake.nix`. | ||
|
||
The addition of a lockfile, (like the `package-lock.json`/`Cargo.lock`/`poetry.lock` files you may have come across in other programming languages) makes your project truly *pure*, so it will be the same no matter where/when you build it (you can avoid a lot of "it works on my machine" problems), and any dependency can be trivially updated and rolled back, instead of dealing with channels via the `nix` cli or manually regenerating hashes for fetchers like `fetchTarball`. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I suggest extracting the comparison to other lock-files into a footnote for readability's sake |
||
|
||
The addition of a centralized entrypoint is less of a direct benefit to your individual config, but makes it easier to compose other projects together, as they all follow a consistent layout for outputs. | ||
|
||
The `flake.nix` file is split into two major parts, the inputs and outputs. | ||
|
||
The inputs includes a list of all 3rd party code included in the project. This commonly includes [nixpkgs](https://github.com/NixOS/nixpkgs) and, on NixOS, [home-manager](https://github.com/nix-community/home-manager). But it can also include any git repository. | ||
|
||
The outputs point to everything which is created by the Nix project. This can include [dev shells](https://nix.dev/tutorials/first-steps/declarative-shell.html), applications, or entire NixOS configurations (and you can have as many of these in one set of outputs as you'd like, having 10 NixOS configs, some applications and a handful of devshells all as the outputs of one flake is perfectly valid). | ||
|
||
To put it simply, inputs are the materials used to build something with Nix. Outputs are the things Nix is going to build using those materials. | ||
|
||
## Why use flakes? | ||
|
||
The primary benefit flakes give is making Nix truly reproducable/pure. Without flakes, there is no way to include specific versions of git repos like nixpkgs in a Nix project. This can cause issues when sharing a project with others, as users could be using different versions of nixpkgs, causing bugs and conflicts. Flakes solve this with the flake.lock file. This file is automatically generated and pins all inputs to a specific git commit. This ensures that everyone using the Nix project is running the same version of nixpkgs and any other inputs. This setup, again, is nothing new. A flake is just a dependency lock file, which are commonly found in other programming languages, especially Node.JS, which uses a package.json and package.lock file. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This is not correct, as both |
||
|
||
## How can I use flakes? | ||
|
||
To begin with using flakes, you need to enable flakes on your system. This can be done by editing `/etc/nix/nix.conf` or your NixOS configuration. | ||
|
||
For non-NixOS systems, add the following to `/etc/nix/nix.conf` or `~/.config/nix/nix.conf`: | ||
|
||
``` | ||
experimental-features = nix-command flakes | ||
``` | ||
|
||
For NixOS systems, add the following to your NixOS configuration: | ||
|
||
```nix | ||
# configuration.nix | ||
nix.settings.experimental-features = [ "nix-command" "flakes" ]; | ||
``` | ||
|
||
Next, initialise a Nix flake in your project using the `nix flake init` command. This will create a basic flake.nix and flake.lock, which should look like this: | ||
|
||
```nix | ||
# flake.nix | ||
{ | ||
description = "A very basic flake"; | ||
|
||
inputs = { | ||
nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable"; | ||
}; | ||
|
||
outputs = { self, nixpkgs }: { | ||
|
||
packages.x86_64-linux.hello = nixpkgs.legacyPackages.x86_64-linux.hello; | ||
|
||
packages.x86_64-linux.default = self.packages.x86_64-linux.hello; | ||
|
||
}; | ||
} | ||
``` | ||
|
||
The default flake template includes a description, a list of inputs including nixpkgs, and a set of packages as outputs. There are many different possible types of outputs, which are all used by different nix commands and projects. In this instance, the `packages.x86_64-linux.default` output is used by the `nix build .` command, which builds the package and adds it to the nix store. The most common output type, and the most important one for this guide, is `nixosConfiguration."<hostname>"`. This outputs a NixOS configuration which is used by `nixos-rebuild switch`. Here is an example of a basic flake for a NixOS configuration: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Cite or provide examples for other outputs. |
||
|
||
```nix | ||
# flake.nix | ||
{ | ||
description = "A very basic flake"; | ||
|
||
inputs = { | ||
nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable"; | ||
}; | ||
|
||
outputs = { self, nixpkgs, ... } @ inputs: { | ||
nixosConfiguration.nixos-system = { | ||
specialArgs = {inherit inputs;}; | ||
modules = [ | ||
./configuration.nix | ||
]; | ||
}; | ||
}; | ||
} | ||
``` | ||
|
||
This file includes a few new parts. First, the `{ self, nixpkgs }` has been changed to `{ self, nixpkgs, ... } @ inputs`. This allows for the flake to recognise any inputs passed in, rather than only being able to use nixpkgs. Next, the packages have been replaced with a `nixosConfiguration.nixos-system`. This exposes a new nixos configuration with the hostname nixos-system to `nixos-rebuild`. When using this in a real system, make sure to change nixos-system to whatever your system hostname is. Thirdly, the `specialArgs = {inherit inputs;};` allows other files to access the flake inputs. Finally, the modules list includes every file imported into the NixOS config. This file can be placed alongside an existing NixOS configuration to add flakes to it. Using `nixos-rebuild switch` will create a flake.lock file and begin using flakes. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The main "benefit" of The first sentence is incorrect.
This does not have to be the hostname. The name is just to identify the contents of the set, nothing more. A system's hostname must be set with |
||
|
||
## Adding extra inputs to Flakes | ||
|
||
One of the key benefits of flakes is the ability to use code from other projects. For example, the Hyprland WM has a flake, allowing you to use the latest builds rather than the build included in nixpkgs. This can be done using the following example: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is not exclusive to flakes. You seem to have misunderstood what flakes are, and what comparative advantages they provide over non-flakes. |
||
|
||
```nix | ||
# flake.nix | ||
{ | ||
description = "A very basic flake"; | ||
|
||
inputs = { | ||
nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable"; | ||
hyprland.url = "github:hyprwm/Hyprland"; | ||
}; | ||
|
||
outputs = { self, nixpkgs, ... } @ inputs: { | ||
nixosConfiguration.nixos-system = { | ||
specialArgs = {inherit inputs;}; | ||
modules = [ | ||
./configuration.nix | ||
]; | ||
}; | ||
}; | ||
} | ||
``` | ||
|
||
```nix | ||
# configuration.nix | ||
{inputs, pkgs, ...}: { | ||
programs.hyprland = { | ||
enable = true; | ||
# set the flake package | ||
package = inputs.hyprland.packages.${pkgs.stdenv.hostPlatform.system}.hyprland; | ||
portalPackage = inputs.hyprland.packages.${pkgs.stdenv.hostPlatform.system}.xdg-desktop-portal-hyprland; | ||
}; | ||
} | ||
``` | ||
|
||
The change made to the flake.nix adds a new input, which pulls code from Hyprland's git repo. The configuration.nix can then be updated to use the package pulled from the git repo, instead of using the nixpkgs package. | ||
|
||
## Further reading | ||
|
||
If flakes still confuse you, [this video by Vimjoyer](https://www.youtube.com/watch?v=JCeYq72Sko0) is a great source which teaches everything you need to know about flakes. All of Vimjoyer's content is very useful and is highly recommended when learning Nix and NixOS. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I do not encourage shilling of content creators for the purposes of a technical documentation. For the sake of clarity, avoid linking personal blogs or youtube channels. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was kinda hoping we could link to the NixOS and Flakes book for further reading But yeah, we should probably avoid linking YouTube videos |
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not necessarily true, nor is it elaborated on.
Flakes have been a difficult concept for as long as they have been around, but their use for NixOS configurations (for, not in) does not add any added complexity.
nixosConfigurations
is a part of the schema, and flakes almost exclusively consume other items from the the schema, even when they are used outside the context of NixOS.