Including homeConfigurations in nixosConfigurations

Hello,

I would like to have a flake that defines the NixOS configurations for multiple systems but can also be used to generate home-manager configurations for non-NixOS (multi-user HPC) systems. I would like to modularize the home-manager configurations and include them in the NixOS configurations, so that users have the same experience on NixOS and non-NixOS systems. This is the minimal working example flake.nix that I have come up with (compile using nixos-rebuild build --flake .#

{
    description = "All the machines";

    inputs = {
        nixpkgs.url = "github:nixos/nixpkgs?ref=release-24.05";
        home-manager.url = "github:nix-community/home-manager?ref=release-24.05";
        home-manager.inputs.nixpkgs.follows = "nixpkgs";
    };

    outputs = { nixpkgs, home-manager, ... } @ inputs:
    rec
    {
        myusercfg = {
                        home.stateVersion = "24.05";
                        home.username = "myuser";
                        home.homeDirectory = "/home/myuser";
                    };
        homeConfigurations = {
            myuser = home-manager.lib.homeManagerConfiguration {
                pkgs = nixpkgs.legacyPackages.x86_64-linux;
                modules = [
                    ({ pkgs, lib, ... }: myusercfg)
                    # more modules
                ];
            };
        };
    
        nixosConfigurations.mymachine = nixpkgs.lib.nixosSystem {
            modules = [
                home-manager.nixosModules.default
                ({ pkgs, home-manager, lib, ...}: {
                    #imports = [ home-manager.nixosModules.default ];
                    imports = [];
                    config = {
                        users.users."myuser" = {
                            isNormalUser = true;
                        };                          
                        #home-manager.users.myuser = myusercfg;    # <---- this works
                        home-manager.users.myuser = homeConfigurations.myuser.config;  # <---- this doesn't work, why?

                        # fake hardware config just so everything builds without errors
                        system.stateVersion = "24.05";
                        networking.hostName = "mymachine";
                        nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
                        boot.initrd.availableKernelModules = [ "ahci" "xhci_pci" "ehci_pci" "nvme" "usbhid" "usb_storage" "sd_mod" "sr_mod" ];
                        boot.initrd.kernelModules = [ ];
                        boot.kernelModules = [ "kvm-intel" ];
                        boot.extraModulePackages = [ ];
                        boot.loader.systemd-boot.enable = true;
                        fileSystems."/" = {
                            device = "/dev/disk/by-uuid/some-uuid";
                            fsType = "ext4";
                        };
                        boot.initrd.luks.devices."luks-root".device = "/dev/disk/by-uuid/some-other-uuid";                          
                    };
                })
            ];
        };
    };
}

Now the problem is that I would like to use the same modules for the home-manager and NixOS users. If I set the configuration manually in the line

home-manager.users.myuser = myusercfg;    # <---- this works

everything works (but I don’t have the module system, so this is not a good option). I think that I should be able to extract the full configuration from the homeConfiguration as in the second line

home-manager.users.myuser = homeConfigurations.myuser.config;  # <---- this doesn't work, why?

but it just produces an error

trace: Obsolete option `programs.zsh.zproof' is used. It was renamed to `programs.zsh.zprof'.
trace: Obsolete option `programs.mako' is used. It was renamed to `services.mako'.
trace: Obsolete option `targets.genericLinux.extraXdgDataDirs' is used. It was renamed to `xdg.systemDirs.data'.
error:
       … while calling the 'head' builtin

         at /nix/store/4xhpzydywjb19d0v2sr9nf3dpnzl6r9i-source/lib/attrsets.nix:1575:11:

         1574|         || pred here (elemAt values 1) (head values) then
         1575|           head values
             |           ^
         1576|         else

       … while evaluating the attribute 'value'

         at /nix/store/4xhpzydywjb19d0v2sr9nf3dpnzl6r9i-source/lib/modules.nix:809:9:

          808|     in warnDeprecation opt //
          809|       { value = builtins.addErrorContext "while evaluating the option `${showOption loc}':" value;
             |         ^
          810|         inherit (res.defsFinal') highestPrio;

       (stack trace truncated; use '--show-trace' to show the full trace)

       error: evaluation aborted with the following error message: 'Renaming error: option `home.pointerCursor.x11.defaultCursor' does not exist.'

I don’t understand why. I can even set “home.pointerCursor.x11.defaultCursor” manually in myusercfg without errors, so why doesn’t it work like this?

Because it’s not a module.
Simple fix: add the relevant module(s) to imports instead.

What is not a module? Adding the home-manager modules to the NixOS configuration doesn’t work, because they work on completely different sets of options.

The homeConfigurations outputs are not modules.

https://nix-community.github.io/home-manager/index.xhtml#sec-flakes-nixos-module

1 Like

Thanks, I figured it out. I didn’t have in mind that home.users.myuser is actually a module and couldn’t figure out how to construct the home manager configuration inside the NixOS module from multiple home manager modules. I’m now setting it to

home.users.myuser = {
    imports = [ ...my list of home manager modules ... ];
}

which works fine.