I recently created NixOS Config Base, a modularized base for more advanced NixOS configurations. It aims to help produce modularized NixOS configurations quickly and easily.
I have created a personal NixOS config based on this.
I want to split configuration of my desktop PC into multiple modules but I was not able to come up with a consistent system that makes sense. It is a hard problem.
I am not particularly convinced system.nix × packages.nix dichotomy is a good idea since the line between user space and system is bit blurry. For example, does services.xserver.desktopManager.gnome.enable = true; go to system? What about environment.systemPackages = [pkgs.gnomeExtensions.dash-to-dock];? And most software is distributed as a package, yet sometimes it needs to be installed using a module – like programs.wireshark.enable = true; which also creates the necessary user group.
The cleanest I have seen were concern-based categories (e.g. desktop-environment.nix, development-tools.nix…), rather than grouping by type (e.g. services.nix, programs.nix…).
It is a bit easier on servers, since there I can split the configuration hierarchically based on domain name. Although some services like nginx are still stuck in top-level configuration.nix.
How about a heirarchy of functionality (for example GNOME shell config would go in desktop-environment/GNOME/shell.nix), using a tree of includes, so there might be a include.nix in every directory, which includes all include.nix one level down plus all other nix files in the current directory?
How about a heirarchy of functionality (for example GNOME shell config would go in desktop-environment/GNOME/shell.nix), using a tree of include s, so there might be a include.nix in every directory, which includes all include.nix one level down plus all other nix files in the current directory?
The list given by @jtojnar is very helpful for getting some inspiration. For directories, you typically have a top-level default.nix which imports all .nix files in the directory. You don’t need to type out default.nix when importing the directory (./dir implies ./dir/default.nix).
Furthermore, you can define custom options that activate other configs. For example, my modules/desktop/default.nix is always imported but it does nothing until I set zhaofeng.desktop.enable = true;.
Yes, I have something similar based on various roles (home network member → various dns, ntp and backup settings; general desktop → DE and other tools; development → vscode and friends that aren’t in per-project devshells; photography; work stuff; etc) and a set of various container definitions that might notionally be run on any of the hosts.
Another repository I’ve taken inspiration from calls them traits.
I’ve used many classification systems or methods over the years.
After a while you always end up with a “misc” file/directory/box in which you stuff everything
And then you start all over again…