Nix: Getting started with Flakes

I've been using NixOS for a few months now, and so far I've avoided flakes and not really understood why to use flakes or what they are. These are my notes from attempting to set up an initial flake controlled NixOS installation.

What are flakes?

So that seems like an improvement. Channels have always seemed a bit iffy to me, given that you'd need to know which channels were used in order to reproduce a configuration.nix otherwise.

Enabling flakes in NixOS

If flakes are not enabled in your config (they are disabled by default as an "experimental" feature as of 23.05), add this to your NixOS config (/etc/nixos/configuration.nix by default):

nix.settings.experimental-features = [ "nix-command" "flakes"];

Run:

$ sudo nixos-rebuild switch

Now we have a nix install with flakes enabled.

Minimal flake

It just contains a description, an input attr set and an output attr set.

{
  description = "My system configuration flake";

  inputs = {};

  outputs = {};
}

Inputs

Inputs is a set of git repos referencing nix package sets. Most obviously and importantly, we'll need nixpkgs. For example like this to set up the 23.05 stable branch:

{
  description = "My system configuration flake";

  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.05"; # Could be simplified to nixpkgs/nixos-23.05 with builtin magic for nixpkgs.
  };

  outputs = {};
}

Outputs

Your system configuration

{
  description = "My system configuration flake";

  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.05"; # Could be simplified to nixpkgs/nixos-23.05 with builtin magic for nixpkgs.
  };

  outputs = {self, nixpkgs, ...}: {

    nixosConfigurations = {
      iron = nixpkgs.lib.nixosSystem {
         system = "x86_64-linux";
         modules = [ ./iron/configuration.nix ];
      };
    };
  };
}

Note it says nixosConfigurations in plural. You can specify multiple NixOS configurations, one for each host. For each host, you specify which system architecture it is, and which nix modules specify the system configuration.

Activating a flake

sudo nixos-rebuild switch --flake .

Forgotten files

If you get something like this, and are in a git repo - but you are referencing files which are not yet added and committed. Then you need to add and commit those files first:

$ nix flake update
error: getting status of '/nix/store/ad4s1wajy1dmadsx4xngw6kmva4dww1v-source/flake.nix': No such file or directory

In general, it seems that it's best to work from a clean git repo state, with everything committed.

Deploying flakes to a remote machine

nixos-rebuild switch --flake .#nixos-public-services --target-host [email protected]

Upgrading flakes

Pinned versions in flakes.lock can be upgraded with nix flake update. Note that this will only update the flakes.lock file, not perform the actual upgrade, so it needs to be followed by nixos-rebuild switch --flake ..

NixOS stable + Unstable + Home-manager

My actual configuration is a bit more complex. I want the ability to pull some packages from unstable (looking at you, signal, for expiring releases within months) and using the popular home-manager module:


{
  description = "My system configuration flake";

  inputs = {
    nixpkgs.url = "nixpkgs/nixos-23.05";
    unstable.url = "nixpkgs/nixos-unstable";
    home-manager.url = "github:nix-community/home-manager/release-23.05";
    home-manager.inputs.nixpkgs.follows = "nixpkgs";
  };

  outputs = {self, nixpkgs, unstable, home-manager, ...}: {

    nixosConfigurations = {
      iron = nixpkgs.lib.nixosSystem rec {
        system = "x86_64-linux";
        modules = let
          defaults = { pkgs, ...}: {
            _module.args.unstable = import unstable { inherit system; };
            _module.args.home-manager = import home-manager.nixosModules.home-manager {};
          }; in
          [
            defaults
            ./iron/configuration.nix
            home-manager.nixosModules.home-manager
          ];
      };
    };
  };
}

Prev: HlK-LD2410C radar presence sensors, MQTT and home assistant [DRAFT]