Is there a way to extend the default list of modules imported via an overlay of some sort?

I’ve been making use of the overlays system to extend the package set of Nixpkgs. Thus creating a custom package set on top of Nixpkgs.

I’ve also created a custom list of modules. So far I create a modules-list.nix similar to nixos/modules-list.nix.

I can override the nixos function and add this as a default modules list for all configuration to make use of.

However does this work with using nixos-rebuild or nixos-install of a custom configuration.nix?

To clarify, I’d like to not use the imports inside configuration.nix. Instead I hope that the custom modules created are automatically imported just like the modules in modules-list.nix.

I’d like an easy way to extend Nixpkgs/NixOS in terms of both package set and custom modules without the need to maintain a fork of nixpkgs, and without using channels, and at the same time pinning the exact revision/hash of Nixpkgs that I’m extending.

Then have this extension work system wide, so that I can have a configuration.nix that uses options like programs.someCrazyThing.enable = true; without having to do a imports = [...]; (because the very act of extending nixpkgs/nixos means that I’ve also extended the custom module-list.nix too.) And then commands like nixos-install and nixos-rebuild and all nix-* commands all work.

There are some issues with overlays, using -I or NIX_PATH that all seem problematic. Also this issue: https://github.com/NixOS/rfcs/pull/49

So far I’ve been using an overlay that overrides the nixos function so I can build my own custom ISOs and other images that already have my own modules loaded in.

This also requires me to build my own ISOs so that nixos-install works.

There is NIXOS_EXTRA_MODULE_PATH, which you can point to custom module

Another way is to wrap nixpkgs directory.

  1. Create a nixpkgs-wrap directory
  2. Create nixpkgs-wrap/nixos directory
  3. echo 'import /path/to/nixpkgs' > nixpkgs-wrap/default.nix
echo '{}: let eval = import /path/to/nixpkgs/nixos/lib/eval-config.nix { 
     system = builtins.currentSystem;
     baseModules = [ ... list of new base modules ... ]; 
}; in { system = eval.config.system.build.toplevel; } ' > nixpkgs-wrap/nixos/default.nix
  1. Point your <nixos> and <nixpkgs> to this nixpkgs-wrap, it should have new base modules

Problem with pointing <nixos> and <nixpkgs> to the nixpkgs-wrap directory is that the existing paths of <nixpkgs/nixos/...> or <nixos/...> all fail. Because those paths expect to be using the upstream nixpkgs repository path.

My original idea was to make use of a new environment variable like <mymodules>, but I wasn’t sure how to do this without always setting that path variable into NIX_PATH. I also thought that since all modules can take extra parameters like modulesPath, I could also supply a special parameter, but that would require adding extraArgs or specialArgs to eval-module.nix.

I’ve read that NIXOS_EXTRA_MODULE_PATH is being deprecated.

I think a better solution would be something like overlay for pkgs, but also overlay for modules. That is right now, modules appears to rely on the filesystem to compose together, but instead we should have a attribute set just like pkgs in Nixpkgs, but for modules instead like modules.

Then one should be able to “overlay” modules without worrying about filesystem paths.

If you don’t want to override all base modules, then I can suggest another way.

Structure your module as:

# my-nginx-module.nix
{ config, pkgs, lib, ... }: {
  disabledModules = [ "services/web-servers/nginx" ];
  options = ...;
  config = ...;
}

(or without disabledModules if you are adding new module, not replacing)

Put those into /etc/nixos/extra-modules. Add a file /etc/nixos/extra-modules/default.nix from

Then add imports = [ ./extra-modules ]; in /etc/nixos/configuration.nix.

Then, you can add any amount of modules to your ./extra-modules folder and they will be discovered dynamically, just like overlays are. And with disabledModules you can replace modules as well.