Home-manager flake without hardcoded system

Hi,

The home-manager docs give a starting example which includes hardcoding the system value. Is it possible to create a flake that works across any system?

I tried using flake-utils but I suspect I’m misunderstanding something because it’s not working like I expected:

{
  inputs = {
    flake-utils.url = "github:numtide/flake-utils";
    home-manager.url = "github:nix-community/home-manager";
    home-manager.inputs.nixpkgs.follows = "nixpkgs";
    nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
  };

  outputs = { flake-utils, home-manager, nixpkgs, ... }:
    flake-utils.lib.eachDefaultSystem (system:
      let
        username = "test";
        pkgs = import nixpkgs {
            inherit system;
          };
      in {
        homeConfigurations.${username} = home-manager.lib.homeManagerConfiguration {
          inherit system username pkgs;

          configuration = import ./home.nix;
          homeDirectory = "/home/${username}";
        };
      }
    );
}

The error returned:

$ nix build --no-link .#homeConfigurations.test.activationPackage

error: flake 'path:/workspace' does not provide attribute 'packages.aarch64-linux.homeConfigurations.test.activationPackage', 'legacyPackages.aarch64-linux.homeConfigurations.test.activationPackage' or 'homeConfigurations.test.activationPackage'

It helps knowing what that function actually does: https://github.com/numtide/flake-utils/blob/12806d31a381e7cd169a6bac35590e7b36dc5fe5/default.nix#L94

I.e., it converts homeConfigurations.test.activationPackage into homeConfigurations.<system>.test.activationPackage, and repeats that for all default systems. In other words, your command should probably be:

nix build --no-link .#homeConfigurations.x86_64-linux.test.activationPackage

In case you hadn’t realized, nix itself has no support for home-manager, and this flake output should be considered a nonstandard extension. Hence nix build won’t manage the system setting for you, unlike how it behaves for other flake outputs.

That said, home-manager (the application) has a --flake switch, which should be preferred over hand invoking things with nix build. As of roughly a year ago it also did not support specifying the system in the usual flake way either, though, and I don’t think that has changed, so I believe this use case is unsupported.

Personally, I have a little comment with a TODO note in my config telling me to do something about that upstream. I’ve been shy to report it, though, probably because I’m a little annoyed I didn’t catch this when I reviewed the PR that added flake support in the first place :wink:

That’s unfortunate it’s not supported. The context I’m working within is container images that are being built for x86 and aarch64 Linux. I was hoping to avoid having to find a way to hack in generating and calling the right config using runtime data in the Dockerfile.

Thanks for explaining the situation, though :slight_smile:

1 Like

No idea if this is feasible for your use case, but if you build those images with nix, you can expose them as derivations in packages and use flake-utils after all.

Nixpkgs has good support for working with OCI images: Nixpkgs 23.11 manual | Nix & NixOS

flake-utils’s eachSystem produce a target hello.aarch64-linux

but home-manager needs packages.aarch64-linux.homeConfigurations .so just add package:

{
  inputs = {
    flake-utils.url = "github:numtide/flake-utils";
    home-manager.url = "github:nix-community/home-manager";
    home-manager.inputs.nixpkgs.follows = "nixpkgs";
    nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
  };

  outputs = { flake-utils, home-manager, nixpkgs, ... }:
    flake-utils.lib.eachDefaultSystem (system:
      let
        username = "test";
        pkgs = import nixpkgs {
          inherit system;
        };
      in
      {
        package = {
          homeConfigurations.${username} = home-manager.lib.homeManagerConfiguration {
            inherit system username pkgs;

            configuration = import ./home.nix;
            homeDirectory = "/home/${username}";
          };
        };
      }
    );
}

then run nix flake show . you will see:

git+file:///xxx/.config/nixpkgs
└───packages
    ├───aarch64-darwin
    │   └───homeConfigurations omitted (use '--all-systems' to show)
    ├───aarch64-linux
    │   └───homeConfigurations omitted (use '--all-systems' to show)
    ├───x86_64-darwin
    │   └───homeConfigurations omitted (use '--all-systems' to show)
    └───x86_64-linux