Testing a new module and package (without breaking my stable nixos install)

Hello all,

I’m trying to test a new module that I’ve written for a package that is in the unstable nixpkgs: static-web-server. Here is my module so far: Comparing NixOS:master...mac-chaffee:sws-module · NixOS/nixpkgs · GitHub

If you had to review my PR, how would you test it out?

Here’s what I know so far:

  • Since I’m using modules, those are for nixos, not nix. So most all of the “nix-” CLI tools won’t help me test this; I need “nixos-” commands. So the docs for testing packages with “nix-shell” don’t apply: Nixpkgs/Create and debug packages - NixOS Wiki
  • I don’t want to use nixos-rebuild -I nixpkgs=/path/to/my/fork (mentioned here and here) since this would rebuild a ton of stuff since my nixos server is currently using the stable version of nixpkgs.
  • Likewise the official docs tell me to build a whole VM using unstable/un-cached nixpkgs, which I fear would take a long time as well: NixOS modules - NixOS Wiki
  • I guess I could stash my changes to nixpkgs, re-apply them to the stable branch of nixpkgs, and re-rsync the files onto my nixos server (and reverse the process before submitting my PR). But the nixpkgs repo is large and git operations and rsyncs are slow. Seems like there must be a better way.
  • I saw this comment which looks promising since it seems like it will build a minimal VM that only has my package installed. But the syntax isn’t quite right and doesn’t allow for importing my package on top of nixpkgs.

Ideally, I’d like to tell nixos “Take my current system, overlay my static-web-server module from <file path> and the unstable static-web-server package from <file path>, and build it” but not sure how to do that. Any hints?

You can try NixOS tests for simple enough cases. But applying a module from your fork to the current system is easy enough too:

let myPkgs = import /path/to/my/fork {};
  imports = [ "${myPkgs}/nixos/modules/my-module.nix" ];
  nixpkgs.overlays = [ (final: prev: {
    inherit (myPkgs) myPackage;

Hmm I couldn’t figure out exactly how to get that method working. Or at least I didn’t want to copy/paste stuff I didn’t fully understand (final? prev? and does it affect how I refer to services.static-web-server?).

Here’s what I ended up doing instead. I already had this block in my configuration.nix in order to install static-web-server from unstable in the first place:

# Allow installing unstable packages
nixpkgs.config = {
    packageOverrides = pkgs: with pkgs; {
      unstable = import unstableTarball {
        config = config.nixpkgs.config;

So I modified it to use my local clone of nixpkgs:

nixpkgs.config = {
    packageOverrides = pkgs: with pkgs; {
      unstable = import "/home/myuser/nixpkgs" {
        config = config.nixpkgs.config;

Then I had to go to my module (static-web-server.nix) and update all the pkgs.static-web-server references to be pkgs.unstable.static-web-server instead. At that point, I was able to make edits to my module and just run nixos-rebuild test repeatedly as my development loop.

Probably not optimal, so anyone reading this should take it with a grain of salt.

Huh? Un-cached? Unstable? Says no such thing. nixos-rebuild build-vm uses the same nixpkgs as usual and all the normal stuff is cached. The VMs built this way are extremely lightweight, sharing their nix store with the host. In fact, for automated testing, there’s even the closely related pkgs.nixosTest for quickly and automatically testing fairly complicated networks of VMs all within a nix build. I use it all the time.

nixos-rebuild build-vm uses the same nixpkgs as usual

That’s the problem: My host uses stable nixpkgs, but the package static-web-server only exists in unstable. I could develop on the master branch where my changes are based, but the docs say “If you’re developing on top of master, this will potentially cause the compilation of lots of packages, since changes on master might not cached on cache.nixos.org yet.”

You can use build-vm with nixos-unstable instead of your system nixpkgs. Just use -I nixpkgs=/path/to/nixpkgs to use a different nixpkgs. Note that nixos-unstable is different from master. While master is quite likely to have a lot of uncached pacakges, nixos-unstable will always have most things cached.

Also, if you’re just looking to test things and don’t want to actually deploy to your real system, I strongly recommend familiarizing yourself with NixOS tests. It’s an extremely good way to automate testing NixOS setups without having to worry about a bunch of state kicking around or having to install NixOS on something.