Flakes: Difference between revisions
remove untrue or unqualified statements Tags: Mobile edit Mobile web edit |
Fix flake refs, remove system from lib.nixosSystem remove flake-utils, clarify some examples |
||
| Line 31: | Line 31: | ||
Add the following to your home-manager config: | Add the following to your home-manager config: | ||
< | <syntaxhighlight lang="nix"> | ||
nix | nix.settings.experimental-features = [ "nix-command" "flakes" ]; | ||
</syntaxhighlight> | |||
</ | |||
=====Other Distros, without Home-Manager===== | =====Other Distros, without Home-Manager===== | ||
| Line 91: | Line 88: | ||
Nixpkgs can be defined using the following code: | Nixpkgs can be defined using the following code: | ||
<code>inputs.nixpkgs.url = "nixpkgs/<branch name>";</code> | <code>inputs.nixpkgs.url = "github:NixOS/nixpkgs/<branch name>";</code> | ||
For any repository with its own flake.nix file, the website must also be defined. Nix knows where the nixpkgs repository is, so stating that it's on GitHub is unnecessary. | For any repository with its own flake.nix file, the website must also be defined. Nix knows where the nixpkgs repository is, so stating that it's on GitHub is unnecessary. | ||
| Line 105: | Line 102: | ||
Using curly brackets({}), we can shorten all of this and put it in a table. The code will look something like this:<syntaxhighlight lang="nix"> | Using curly brackets({}), we can shorten all of this and put it in a table. The code will look something like this:<syntaxhighlight lang="nix"> | ||
inputs = { | inputs = { | ||
nixpkgs.url = "nixpkgs/<branch name>"; | nixpkgs.url = "github:NixOS/nixpkgs/<branch name>"; | ||
hyprland = { | hyprland = { | ||
url = "github:hyprwm/Hyprland"; | url = "github:hyprwm/Hyprland"; | ||
| Line 205: | Line 202: | ||
and add <code>flake-compat</code> to the arguments of <code>outputs</code> attribute. Then you will be able to use <code>default.nix</code> like the following: | and add <code>flake-compat</code> to the arguments of <code>outputs</code> attribute. Then you will be able to use <code>default.nix</code> like the following: | ||
< | <syntaxhighlight lang="nix"> | ||
(import ( | (import ( | ||
let | let | ||
lock = builtins.fromJSON (builtins.readFile ./flake.lock); | lock = builtins.fromJSON (builtins.readFile ./flake.lock); | ||
in fetchTarball { | nodeName = lock.nodes.root.inputs.flake-compat; | ||
url = "https://github.com/edolstra/flake-compat/archive/${lock.nodes. | in | ||
sha256 = lock.nodes. | fetchTarball { | ||
) { | url = | ||
lock.nodes.${nodeName}.locked.url | |||
}).defaultNix | or "https://github.com/edolstra/flake-compat/archive/${lock.nodes.${nodeName}.locked.rev}.tar.gz"; | ||
</ | sha256 = lock.nodes.${nodeName}.locked.narHash; | ||
} | |||
) { src = ./.; }).defaultNix | |||
</syntaxhighlight> | |||
== Accessing flakes from Nix expressions == | == Accessing flakes from Nix expressions == | ||
If you want to access a flake from within a regular Nix expression on a system that has flakes enabled, you can use something like <code>(builtins.getFlake " | If you want to access a flake from within a regular Nix expression on a system that has flakes enabled, you can use something like <code>(builtins.getFlake "/path/to/directory").packages.x86_64-linux.default</code>, where 'directory' is the directory that contains your <code>flake.nix</code>. | ||
== Making your evaluations pure == | == Making your evaluations pure == | ||
| Line 229: | Line 229: | ||
* Imports from channels like <code><nixpkgs></code> can be made pure by instead importing from the <code>output</code> function in <code>flake.nix</code>, where the arguments provide the store path to the flake's inputs: | * Imports from channels like <code><nixpkgs></code> can be made pure by instead importing from the <code>output</code> function in <code>flake.nix</code>, where the arguments provide the store path to the flake's inputs: | ||
< | <syntaxhighlight lang="nix"> | ||
outputs = { self, nixpkgs, ... }: | outputs = { self, nixpkgs, ... }: | ||
{ | { | ||
nixosConfigurations.machine = nixpkgs.lib.nixosSystem { | nixosConfigurations.machine = nixpkgs.lib.nixosSystem { | ||
modules = [ | modules = [ | ||
"${nixpkgs}/nixos/modules/<some-module>.nix" | |||
./machine.nix | ./machine.nix | ||
]; | ]; | ||
}; | }; | ||
}; | }; | ||
</ | </syntaxhighlight> | ||
== The nix flakes command == | == The nix flakes command == | ||
| Line 257: | Line 255: | ||
A basic nixos flake.nix could look like this: | A basic nixos flake.nix could look like this: | ||
< | <syntaxhighlight lang="nix"> | ||
{ | { | ||
inputs.nixpkgs.url = github:NixOS/nixpkgs/nixos-unstable; | |||
outputs = { self, nixpkgs }: { | outputs = { self, nixpkgs }: { | ||
# replace 'joes-desktop' with your hostname here. | # replace 'joes-desktop' with your hostname here. | ||
nixosConfigurations.joes-desktop = nixpkgs.lib.nixosSystem { | nixosConfigurations.joes-desktop = nixpkgs.lib.nixosSystem { | ||
modules = [ ./configuration.nix ]; | modules = [ ./configuration.nix ]; | ||
}; | }; | ||
}; | }; | ||
} | } | ||
</ | </syntaxhighlight> | ||
If you want to pass on the flake inputs to external configuration files, you can use the <code>specialArgs</code> attribute: | If you want to pass on the flake inputs to external configuration files, you can use the <code>specialArgs</code> attribute: | ||
< | <syntaxhighlight lang="nix"> | ||
{ | { | ||
inputs.nixpkgs.url = github:NixOS/nixpkgs/nixos-unstable; | inputs.nixpkgs.url = github:NixOS/nixpkgs/nixos-unstable; | ||
inputs.home-manager.url = github:nix-community/home-manager; | inputs.home-manager.url = github:nix-community/home-manager; | ||
outputs = { self, nixpkgs, ... }@ | outputs = { self, nixpkgs, ... }@inputs: { | ||
nixosConfigurations.fnord = nixpkgs.lib.nixosSystem { | nixosConfigurations.fnord = nixpkgs.lib.nixosSystem { | ||
specialArgs = { inherit inputs; }; | |||
modules = [ ./configuration.nix ]; | modules = [ ./configuration.nix ]; | ||
}; | }; | ||
}; | }; | ||
} | } | ||
</ | </syntaxhighlight> | ||
Then, you can access the flake inputs from the file <code>configuration.nix</code> like this: | Then, you can access the flake inputs from the file <code>configuration.nix</code> like this: | ||
< | <syntaxhighlight lang="nix"> | ||
{ config, lib, | { config, lib, inputs, ... }: { | ||
# do something with home-manager here, for instance: | # do something with home-manager here, for instance: | ||
imports = [ home-manager.nixosModules.default ]; | imports = [ inputs.home-manager.nixosModules.default ]; | ||
... | ... | ||
} | } | ||
</ | </syntaxhighlight> | ||
{{Ic|nixos-rebuild}} also allows to specify different flake using the <code>--flake</code> flag (# is optional): | {{Ic|nixos-rebuild}} also allows to specify different flake using the <code>--flake</code> flag (# is optional): | ||
< | <syntaxhighlight lang="console"> | ||
$ sudo nixos-rebuild switch --flake | $ sudo nixos-rebuild switch --flake . | ||
</ | </syntaxhighlight> | ||
By default nixos-rebuild will use the currents system hostname to lookup the right nixos configuration in <code>nixosConfigurations</code>. You can also override this by using appending it to the flake parameter: | By default nixos-rebuild will use the currents system hostname to lookup the right nixos configuration in <code>nixosConfigurations</code>. You can also override this by using appending it to the flake parameter: | ||
< | <syntaxhighlight lang="console"> | ||
$ sudo nixos-rebuild switch --flake | $ sudo nixos-rebuild switch --flake /etc/nixos#joes-desktop | ||
</ | </syntaxhighlight> | ||
To switch a remote | To switch a remote host you can use: | ||
< | <syntaxhighlight lang="bash"> | ||
$ nixos-rebuild --flake .#mymachine \ | $ nixos-rebuild --flake .#mymachine \ | ||
--target-host mymachine-hostname --build-host mymachine-hostname --fast \ | --target-host mymachine-hostname \ | ||
--build-host mymachine-hostname --fast \ | |||
switch | switch | ||
</ | </syntaxhighlight> | ||
{{warning|Remote building seems to have an issue that's [https://github.com/NixOS/nixpkgs/issues/134952#issuecomment-1367056358 resolved by setting the <code>--fast</code> flag].}} | {{warning|Remote building seems to have an issue that's [https://github.com/NixOS/nixpkgs/issues/134952#issuecomment-1367056358 resolved by setting the <code>--fast</code> flag].}} | ||
== Pinning the registry | == Pinning the registry on NixOS == | ||
< | <syntaxhighlight lang="nix"> | ||
{ inputs, ... }: | |||
nixpkgs. | { | ||
nix.registry = { | |||
nixpkgs.flake = inputs.nixpkgs; | |||
}; | }; | ||
</ | } | ||
</syntaxhighlight> | |||
To make sure the registry entry is "locked", use the following: | To make sure the registry entry is "locked", use the following: | ||
| Line 349: | Line 345: | ||
Let’s say that your project has a <code>shell.nix</code> file that looks like this: | Let’s say that your project has a <code>shell.nix</code> file that looks like this: | ||
< | <syntaxhighlight lang="nix"> | ||
{ pkgs ? import <nixpkgs> { } }: | { | ||
pkgs ? import <nixpkgs> { }, | |||
mkShell { | }: | ||
pkgs.mkShell { | |||
packages = [ pkgs.nixfmt ]; | |||
shellHook = '' | shellHook = '' | ||
| Line 361: | Line 356: | ||
''; | ''; | ||
} | } | ||
</ | </syntaxhighlight> | ||
Running nix-shell can be a bit slow and take 1-3 seconds. | Running nix-shell can be a bit slow and take 1-3 seconds. | ||
| Line 367: | Line 362: | ||
Now create a <code>flake.nix</code> file in the same repository: | Now create a <code>flake.nix</code> file in the same repository: | ||
< | <syntaxhighlight lang="nix"> | ||
{ | { | ||
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; | |||
inputs. | |||
outputs = { | outputs = | ||
{ nixpkgs, ... }: | |||
{ | |||
let pkgs = nixpkgs.legacyPackages. | /* | ||
This example assumes your system is x86_64-linux | |||
change as neccesary | |||
*/ | |||
devShells.x86_64-linux = | |||
let | |||
pkgs = nixpkgs.legacyPackages.x86_64-linux; | |||
in | |||
{ | { | ||
default = pkgs.mkShell { | |||
} | packages = [ pkgs.hello ]; | ||
}; | |||
}; | |||
}; | |||
} | } | ||
</ | } | ||
</syntaxhighlight> | |||
( If you're in a git repository run `git add flake.nix` so that Nix recognizes it. ) | |||
And finally, run <code>nix develop</code>. This is what replaces the old nix-shell invocation. | And finally, run <code>nix develop</code>. This is what replaces the old nix-shell invocation. | ||
| Line 394: | Line 397: | ||
=== Automatically switch nix shells with nix-direnv === | === Automatically switch nix shells with nix-direnv === | ||
You can easily switch nix shells when you cd into different projects with | You can easily switch nix shells when you cd into different projects with [https://github.com/nix-community/nix-direnv nix-direnv]. | ||
== Pushing Flakes to Cachix == | == Pushing Flakes to Cachix == | ||
| Line 400: | Line 403: | ||
https://docs.cachix.org/pushing#flakes | https://docs.cachix.org/pushing#flakes | ||
To push ''all'' flake outputs automatically, | To push ''all'' flake outputs automatically, checkout [https://github.com/srid/devour-flake#usage devour-flake]. | ||
== Build specific attributes in a flake repository == | == Build specific attributes in a flake repository == | ||
| Line 414: | Line 417: | ||
=== Building flakes from a Git repo url with submodules === | === Building flakes from a Git repo url with submodules === | ||
As per nix 2.9.1, git submodules in package <code>src</code>s won't get copied to the nix store, this may cause the build to fail. To workaround this, use: | As per nix 2.9.1, git submodules in package <code>src</code>'s won't get copied to the nix store, this may cause the build to fail. To workaround this, use: | ||
< | <syntaxhighlight lang="console"> | ||
nix build '.?submodules=1#hello' | |||
</ | </syntaxhighlight> | ||
See: https://github.com/NixOS/nix/pull/5434 | See: https://github.com/NixOS/nix/pull/5434 | ||
== Importing packages from multiple | == Importing packages from multiple nixpkgs branches == | ||
A NixOS config flake | A NixOS config flake could be as follows: | ||
< | <syntaxhighlight lang="nix"> | ||
{ | { | ||
description = "NixOS configuration with two or more channels"; | description = "NixOS configuration with two or more channels"; | ||
inputs = { | inputs = { | ||
nixpkgs.url = "nixpkgs/nixos- | nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.11"; | ||
nixpkgs-unstable.url = "nixpkgs/nixos-unstable"; | nixpkgs-unstable.url = "github:NixOS/nixpkgs/nixos-unstable"; | ||
}; | }; | ||
outputs = { | outputs = | ||
{ nixpkgs, nixpkgs-unstable, ... }: | |||
{ | |||
nixosConfigurations."<hostname>" = nixpkgs.lib.nixosSystem { | nixosConfigurations."<hostname>" = nixpkgs.lib.nixosSystem { | ||
modules = [ | modules = [ | ||
{ | |||
nixpkgs.overlays = [ | |||
(final: prev: { | |||
unstable = nixpkgs-unstable.legacyPackages.${prev.system}; | |||
# use this variant if unfree packages are needed: | |||
# unstable = import nixpkgs-unstable { | |||
# inherit system; | |||
# config.allowUnfree = true; | |||
# }; | |||
}) | |||
]; | |||
} | |||
./configuration.nix | ./configuration.nix | ||
]; | ]; | ||
| Line 457: | Line 459: | ||
}; | }; | ||
} | } | ||
</ | </syntaxhighlight> | ||
< | <syntaxhighlight lang="nix"> | ||
# NixOS configuration.nix, can now use "pkgs.package" or "pkgs.unstable.package" | # NixOS configuration.nix, can now use "pkgs.package" or "pkgs.unstable.package" | ||
{ | { pkgs, ... }: | ||
environment.systemPackages = [pkgs.firefox pkgs.unstable.chromium]; | { | ||
environment.systemPackages = [ | |||
pkgs.firefox | |||
pkgs.unstable.chromium | |||
]; | |||
# ... | # ... | ||
} | } | ||
</ | </syntaxhighlight>If the variable <code>nixpkgs</code> points to the flake, you can also define <code>pkgs</code> with overlays with: | ||
<syntaxhighlight lang="nix"> | |||
pkgs = import nixpkgs { system = "x86_64-linux"; overlays = [ /*the overlay in question*/ ]; }; | |||
</syntaxhighlight> | |||
pkgs = import nixpkgs { overlays = [ /*the overlay in question*/ ]; }; | |||
</ | |||
== Getting ''Instant'' System Flakes Repl == | == Getting ''Instant'' System Flakes Repl == | ||
| Line 478: | Line 481: | ||
How to get a nix repl out of your system flake: | How to get a nix repl out of your system flake: | ||
< | <syntaxhighlight lang="text"> | ||
$ nix repl | |||
nix-repl> :lf /path/to/flake | |||
Added 18 variables. | |||
nix-repl> nixosConfigurations.myHost.config.networking.hostName | |||
"myHost" | |||
> | |||
</syntaxhighlight> | |||
<syntaxHighlight lang=nix> | However, this won't be instant upon evaluation if any file changes have been done since your last configuration rebuild. Instead, if one puts:<syntaxHighlight lang=nix> | ||
nix.nixPath = let path = toString ./.; in [ "repl=${path}/repl.nix" "nixpkgs=${inputs.nixpkgs}" ]; | nix.nixPath = let path = toString ./.; in [ "repl=${path}/repl.nix" "nixpkgs=${inputs.nixpkgs}" ]; | ||
</syntaxHighlight> | </syntaxHighlight> | ||