I think I have a rather standard situation, but Im not really sure what the way to go here is.
Setup
I have the following machines:
macOS
:- laptop A, aarch64
nixOS
:- server, x86_64
I currently manage the macOS machine with nix-darwin + home-manager
, the nixOS setup with, well nix + home-manager
. Of course, both machines have things that should be shared, and things that shouldn’t. My config is currently structured like this:
|- flake.nix
|- apps/
| |- build-switch
|- hosts/
| |- darwin/
| |- default.nix
| |- nixOS/
| |- default.nix
|- modules/
| |- shared/
| |- darwin/
| | |- home-manager.nix
| |- nixOS/
| | |- home-manager.nix
This worked so far quite well.
Problem
I need to add an additional MacBook to the setup and a Ubuntu machine. For the new MacBook I will just create a new folders in hosts/darwin
, one for each host, and put the host specific stuff there. What Im not sure is how to do the Ubuntu part… My flake.nix
looks like this:
# flake.nix
{
description = "my config";
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-24.11";
home-manager.url = "github:nix-community/home-manager";
darwin = {
url = "github:LnL7/nix-darwin/master";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs =
{ self
, darwin
, home-manager
, nixpkgs
,
} @ inputs:
let
user = "iilak";
linuxSystems = [ "x86_64-linux" "aarch64-linux" ];
darwinSystems = [ "x86_64-darwin" "aarch64-darwin" ];
forAllSystems = f: nixpkgs.lib.genAttrs (linuxSystems ++ darwinSystems) f;
devShell = system:
let
pkgs = nixpkgs.legacyPackages.${system};
in
{
default = with pkgs;
mkShell {
inherit (preCommitCheck) shellHook;
buildInputs = preCommitCheck.enabledPackages;
nativeBuildInputs = with pkgs; [ bashInteractive git ];
};
};
mkApp = scriptName: targetSystem: system: {
type = "app";
program = "${(nixpkgs.legacyPackages.${system}.writeScriptBin scriptName ''
#!/usr/bin/env bash
PATH=${nixpkgs.legacyPackages.${system}.git}/bin:$PATH
echo "Running ${scriptName} for ${targetSystem}/${system}"
exec ${self}/apps/${scriptName} ${targetSystem} ${system}
'')}/bin/${scriptName}";
};
mkLinuxApps = system: {
"test" = mkApp "build-switch" "test" system;
};
mkDarwinApps = system: {
"mac" = mkApp "build-switch" "mac" system;
};
in
{
devShells = forAllSystems devShell;
apps = nixpkgs.lib.genAttrs linuxSystems mkLinuxApps // nixpkgs.lib.genAttrs darwinSystems mkDarwinApps;
darwinConfigurations = nixpkgs.lib.genAttrs darwinSystems (
system:
darwin.lib.darwinSystem {
inherit system;
specialArgs = { inherit inputs; };
modules = [
home-manager.darwinModules.home-manager
nix-homebrew.darwinModules.nix-homebrew
{
nix-homebrew =
{
inherit user;
enable = true;
mutableTaps = false;
autoMigrate = true;
};
}
./hosts/darwin
];
}
);
nixosConfigurations = nixpkgs.lib.genAttrs linuxSystems (
system:
nixpkgs.lib.nixosSystem {
inherit system;
specialArgs = {inherit inputs;};
modules = [
home-manager.nixosModules.home-manager
{
home-manager = {
useGlobalPkgs = true;
useUserPackages = true;
users.${user} = import ./modules/nixos/home-manager.nix;
};
}
./hosts/nixos
];
}
);
};
}
As you can see I used here nixpkgs.lib.nixosSystem
and darwin.lib.darwinSystem
and then supply the relevant home-manager.nix
as a module. But how do you do this for a scenario where you just want to manage you home directory with home-manager
?
I tried this here, but this feels somehow out of place with the other two configs…
homeConfigurations = {
example_case = home-manager.lib.homeManagerConfiguration
pkgs = nixpkgs.legacyPackages.${system};
modules = [
./modules/ubuntu/example_case/home-manager.nix
];
extraSpecialArgs =
{ inherit inputs; }
// {
isNixOS = false;
impurePaths = {
workingDir = "/home/utm/.config/nix";
};
};
}
};
If you have any specific suggestions, that would be great. Otherwise, some examples of other people doing this kind of thing, would be also much appreciated.
I based a lot of this on this repo, but of course more examples are always welcome.