My setup is very similar.
I have an aarch64 Mac from which I remotely build several NixOS machines using nix run nixpkgs#nixos-rebuild -- --fast --target-host <user>@<ssh_host> --build-host <user>@<ssh_host> --flake .#<nixosConfiguration> --use-remote-sudo switch
If I understand correctly, when your host machine is a different architecture than your target machine you must include --fast
. As per man nixos-rebuild
:
--no-build-nix
Normally, nixos-rebuild first builds the ‘nixUnstable’ attribute in Nixpkgs, and uses the resulting instance of the Nix package manager to build the new system configuration. This is necessary if
the NixOS modules use features not provided by the currently installed version of Nix. This option disables building a new Nix.
--fast Equivalent to --no-build-nix. This option is useful if you call nixos-rebuild frequently (e.g. if you’re hacking on a NixOS module).
--build-host host
Instead of building the new configuration locally, use the specified host to perform the build. The host needs to be accessible with ssh, and must be able to perform Nix builds. If the option
--target-host is not set, the build will be copied back to the local machine when done.
Note that, if --no-build-nix is not specified, Nix will be built both locally and remotely. This is because the configuration will always be evaluated locally even though the building might be
performed remotely.
If you run without --fast
it will attempt to build an incompatible CPU architecture, which will error:
error: a 'x86_64-linux' with features {} is required to build '/nix/store/fvb1k8w9xiil240y5p02x5hzpjqvzyay-nixos-rebuild.drv', but I am a 'aarch64-darwin' with features {apple-virt, benchmark, big-parallel, nixos-test}
Although it is possible to setup cross-compilation, I just haven’t done it yet.
--use-remote-sudo
will prompt the sudo password of your user on the remote target. It may close and create new SSH connections, and thus prompt you multiple times.
I’m not sure how you’d check that the config works on your laptop first. When rebuilding fails, the behavior is the same as when you build a local machine; it exits with an error without applying the rebuild.
Although I haven’t pushed the config of my remote machines to my flake repo yet, here is a simple example.
There’s also several community projects like Colmena and NixOps. I haven’t used them yet, but I will give Colmena a try because it supports parallel builds which I’m gonna need to manage a fleet of servers.