NixOS is a Linux distribution that is built around the Nix package manager. More information is in my previous post(s). This post is about the way I made my Nixos configuration modular and useable on different systems. It mixes a laptop with an erase-your-darlings setup with a more normal Nixos laptop configuration and a server setup. All this while reusing as much of the configuration(s) as possible.
Modularisation Link to heading
The general idea is simple. A Nixos configuration file can include other configuration files, this is done as follows:
{ config, pkgs, ... }:
{
imports =
[ # Include the results of the hardware scan.
./t14s-hardware-configuration.nix
./parts/generic-boot-systemd.nix
./parts/generic-desktop.nix
./parts/generic.nix
./parts/virtualisation.nix
./parts/printing.nix
./parts/users.nix
./parts/apps-default.nix
./parts/apps-extra-cli.nix
./parts/apps-extra-desktop.nix
./parts/apps-extra-music.nix
./parts/fonts.nix
];
The listing above already shows how I like to setup my Nixos configuration. So what I do is isolate related items and combine them into a single reusable configuration. For example, the printing configuration is straightforward and looks as follows:
{ config, pkgs, ... }:
{
services.printing = {
enable = true;
startWhenNeeded = true;
drivers = [
pkgs.splix
pkgs.samsung-unified-linux-driver
];
extraConf = "DefaultAuthType None";
};
}
Each system which includes this configuration will be able to interface with my Samsung laser printer.
A more interesting configuration is my users.nix (which has -obviously- been edited for this post):
{ config, pkgs, ... }:
{
# Define user accounts. Don't forget to set a hashed-password with ‘mkpasswd’.
users.users.patrick = {
isNormalUser = true;
extraGroups = [ "fprint" "wheel" "networkmanager" "docker" "libvirtd" "dialout" ];
shell = pkgs.zsh;
};
# Enable zshell
programs.zsh.enable = true;
# Keyring via PAM
security.pam.services.patrick.enableGnomeKeyring = true;
}
Where the printing configuration basically sets up a single configuration item with the relevant options (services.printing
), this users configuration sets up multiple different configuration items with their relevant options (users.users.patrick
, programs.zsh
, and security.pam
).
I also use a schema to help me identify configuration items by filename. The following listing shows the naming scheme I use:
.
├── parts
│ ├── apps-default.nix
│ ├── apps-extra-cli.nix
│ ├── apps-extra-desktop.nix
│ ├── desktop-gnome.nix
│ ├── desktop-sway.nix
│ ├── fonts.nix
│ ├── generic-boot-systemd.nix
│ ├── generic-desktop.nix
│ ├── generic-server.nix
│ ├── printing.nix
│ ├── server-adguard.nix
│ ├── server-smart.nix
│ ├── server-tailscale.nix
│ ├── users.nix
│ ├── users-patrick.nix
│ ├── users-user2.nix
├── laptop-configuration.nix
├── laptop-hardware-configuration.nix
├── server-configuration.nix
└── server-hardware-configuration.nix
The top-level configuration files combinations (laptop- and server- configurations) will include the relevant configurations from the parts
folder.
Applying this configuration Link to heading
These file are all stored in a git repository. The git repository is then cloned on each of mt Nixos systems.
A default Nixos system setup checks the /etc/nixos
folder for the file configuration.nix
.
Since each system will have a separate setup (at least requiring a separate hardware-configuration file) we need to create the configuration.nix
.
However, that file is already create, but it has a different name.
This we solve by simply symlinking the correct file:
$ cp -r ./* /etc/nixos/
$ ln -s /etc/nixos/desktop-configuration.nix /etc/nixos/configuration.nix
This creates the /etc/nixos/configuration.nix
and prepares the system for standard Nixos commands for building and switching configurations.
Updating a configuration Link to heading
My Nixos configurations are shared between all my systems.
Updating a configuration is simply editing them in the repo, pushing the changes to the remote git repository, and (again) copying the files to the /etc/nixos/
folder (see previous section).
That is all.
It is super simple and easy to setup.
However, it is powerfull, especially when combined with home-manager
(which is a topic for a separate post).