This article discusses managing NixOS configurations using Flakes and Home Manager.
Abstract
This article explains how to manage NixOS configurations using Flakes and Home Manager. Flakes are an experimental feature of Nix that ensures the same inputs always produce the same outputs, allowing for efficient management of system configurations, distribution of nixpkgs overlays, and sharing of system configurations. Home Manager, on the other hand, allows users to manage user environments, including environmental variables, packages, and dotfiles. The article provides a step-by-step guide on how to enable flake support, create a flake file, and install Home Manager as a module.
Opinions
Flakes are a powerful tool for managing NixOS configurations and sharing them with others.
Home Manager is a useful tool for managing user environments and dotfiles.
Using Flakes and Home Manager together can greatly improve the management of NixOS configurations.
Flakes are subject to breaking changes in the future, but they are currently stable and becoming standard for most configurations.
The author recommends using Home Manager as a module rather than as a standalone software.
Managing your NixOS configuration with Flakes and Home Manager!
Nix Flake
If you followed one of my earlier posts about NixOS, then you should already be somewhat familiar with the basics of managing and configuring your NixOS.
However, Nix can be much more than a single configuration.nix file? In this guide we will be setting up not one, BUT TWO powerful tools. Flakes and Home Manager!
Ok, but what are Nix Flakes?
Flakes are an experimental feature of Nix that aims to fix some of the challenges around true reproducibility. They ensure that the same inputs always produce the same outputs.
You can manage your system configurations (yes, plural), distribute nixpkgs overlays, and modules more efficiently. Flakes make it easy to share your entire system down to the exact package version with anyone.
Flakes are stored in a file called flake.nix.
Above is one of the simplest flakes you can make for managing your home system.
The inputs section of the file specifies the flake’s dependencies. Here we have nixpkgs defined. It points to the GitHub URL that contains the unstable branch of nixpkgs. You can look at it here.
The second main part is the outputs. It inherits itself and nixpkgs from the inputs section above. The single output in this case is nixosConfigurations. As it sounds, this output defines the NixOS system configs.
hostName is a placeholder variable for the machine’s name. In most cases, it is named after the machine's hostname (which you can find by typing hostname in the terminal). You can call it whatever, but if it’s not the machine’s hostname then you will have to call that name specifically when building.
It calls the nixpkgs.lib.nixosSystem function. That function specifies the system’s architecture and the modules list. As you might have noticed, modules list contains the relative path to the system configuration file.
When the flake file is built, it creates a flake.lock file. Just like how Javascript has a package.json file and a package-lock.json file, Nix has a flake.nix file and flake.lock file.
Before we move on enabling and creating a flake file, lets touch on Home Manager and how we will be using it.
What is Home Manager?
While /etc/nixos/configuration.nix configures the system, Home Manager takes it a step further and allows you to manage user environments. With the Nix language you can declaratively define user environmental variables, packages, and most importantly, dotfiles.
It can be used a standalone software, allowing users to update their dotfiles without root privileges or as a NixOS module. If it’s a Nix module then you will have to rebuild your system everytime you want to update your dotfiles. I personally have it set as a module, but you can install it standalone as well.
Getting started
To get started you first need to enable flake support. It is technically a experimental feature still, but this is because it’s subject to breaking changes in the future. As of right now it is really stable and is becoming standard for most configurations.
Adding flakes it super simple. Copy this line and add it into your configuration.nix file.
experimental-features= [ "nix-command""flakes" ];
Rebuild you system and then you can start writing flakes.
In the root of your configuration directory /etc/nixos run the command:
nix flake init
This will generate a extremely basic flake.nix file. Go ahead and change the default description to whatever you want and then remove everything from inside the outputs object.
You can copy the flake example from before for you starting flake. To build this flake you will need to run this command from the directory the flake is in.
sudo nixos-rebuild switch --flake .#
The --flake flag points to the flake we are switching too. The period is the directory that the flake is stored in and the number sign specifies the hostname defined in the file. If you called the hostname in the flake the same as the machine host name then you can leave the symbol blank, otherwise you will need to append the hostname defined in the flake to it. Like this .#hostName.
If everything went well then you should have a flake.lock file. If you want, open it up and look around. It will have a bunch of hashes and other stuff. Don’t edit it.
To install home manager go ahead and use this flake file. It will install home manager as a module.
Make sure to replace with your actual username. In the inputs, you might notice that home manager is split into two parts. The GitHub URL points to the master branch. The reason for this is because it follows the unstable branch of nixpkgs. If you are using a stable release of Nix, update the home manager URL accordingly. The line below the URL tells home manager to follow the unstable branch.
Configuring things inside Home Manager
After rebuilding (using the command from before), you can start configuring the ./home.nix file. You can also define the path else where, just make sure its relative to the flake.
Here is an example file. You can install user specific packages and define the dotfile for zsh.
There is a ton more you can do with Home Manager and Flakes too, but there is too much to cover in this one post. Here are some resources that you can use to learn more about them!