I’ve been meaning to write something for a while now, however before I can dive into a couple of more interesting topics here, I feel like it is the best to mention the transition to flakes. I’ll try and keep this one short, there are a bunch of other way more detailed posts on flakes already, however I didn’t find to many posts about how to switch from an existing configuration to using flakes and it seems to be quite doable.
On a freshly installed NixOS system, /etc/nixos
looks like this:
[user@host1:/etc/nixos]$ tree -CL 1
.
├── configuration.nix
└── hardware-configuration.nix
If you’ve played around a bunch, have more than one machine and have at some
point in time started using imports
, it’ll probably look more like this:
[user@host1:/etc/nixos]$ tree -CL 1
.
├── configuration.nix -> hosts/host1/configuration.nix # symlinked nixos configuration (.gitignored)
├── hardware # hardware specific config
├── hosts # contains hosts configuration.nix files
│ ├── host0
│ ├── host1
...
│ └── hostN
├── modules # modular configuration bits and pieces
│ ├── baseUtils
...
│ └── zfs
├── pkgs # packages that aren't part of nixpkgs
├── services # services that are hosted on the hosts
│ ├── host2
│ │ └── nextloud
│ └── host3
│ ├── gitea
│ ├── calendar
│ └── navidrome
├── users # user configurations
└── vpn # vpn configurations
In my case I’ve created a bunch of directories containing the bits and pieces of
configuration I use. Among them is a hosts
directory, which contains all the
host-specific files in host-specific directories and I symlink the
configuration.nix
from there into /etx/nixos/
, so I can conveniently execute
nixos-rebuild switch
. The whole /etc/nixos
directory is a git repo I share
among all of my machines and the .gitignore
file currently contains a single
line:
[user@host1:/etc/nixos]$ cat .gitignore
/configuration.nix
A typical /etc/nixos/configuration.nix
then looks like this, note the paths
are relative from the /etc/nixos/hosts/hostname/
directory:
{ config, pkgs, ... }:
{
imports = [
../../modules/baseUtils
../../services/host2/nextcloud
../../users
./hardware-configuration.nix
./vpn/tinc/networkname
];
boot.loader.grub.enable = true;
boot.loader.grub.version = 2;
boot.initrd.availableKernelModules = [ "e1000e" "virtio_pci" "e1000" ];
...
}
Before switching to flakes I decided to do a bit of housekeeping inside the
/etc/nixos/hosts/hostname
direcories. While this is strictly unnecessary, I
kind of liked the idea:
I renamed /etc/nixos/hosts/host/configuration.nix
to default.nix
and created
a new configuration.nix
, which includes default.nix
:
[user@host1:/etc/nixos/hosts/host0]$ tree -CL 1
.
├── configuration.nix
├── default.nix
└── hardware.nix
Now I can just split my system configurations up into the more host-specific
part, which I very rarely have to look into, containing options such as
boot.loader.grub
and another much shorter part that contains, what the system
is actually configured for in form of module imports. The new configuration
looks so far pretty empty, since we’ve renamed the configuration to
default.nix
, we can just reference it using ./.
:
{ config, pkgs, ... }:
{
imports = [
./. # <- isn't this just beautiful
];
}
But back to topic: in order to start using flakes, we need be enable flakes on
the system, so create ./modules/flakes/default.nix
and import it in
default.nix
:
{ lib, pkgs, config, ... }:
{
nix = {
package = pkgs.nixFlakes;
extraOptions = ''
experimental-features = nix-command flakes
'';
};
}
Rebuild the system to enable the feature.
Then in /etc/nixos
create a minimal flake.nix
file, which contains a link to
the hosts configuration.nix
inside nixosConfigurations
:
{
description = "Oblivious Infrastructure";
inputs = {
flake-utils.url = "github:numtide/flake-utils";
nix.url = "github:NixOS/nix/2.5.1";
nixpkgs.url = "github:NixOS/nixpkgs/nixos-21.11";
nixos-hardware.url = "github:NixOS/nixos-hardware";
};
outputs = { self, nixpkgs, nix, ... }: {
nixosConfigurations = {
host0 = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
./hosts/host0/configuration.nix
];
};
host1 = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
./hosts/host1/configuration.nix
];
};
};
};
}
In order to check if everything works just run nixos-rebuild switch --flake .#host
from /etc/nixos/
or nixos-rebuild switch --flake /etc/nixos/#host
from anywhere else.
Congratulations, your system now runs on flakes.