I want to deploy my NixOS configurations remotely.
I’m currently using a nix flake with a nixosConfigurations output attribute to build configurations for different machines. However, this requires cloning this repo to every machine and building the configuration locally. This makes has security issues (private keys stored on public facing machines), performance implications (requires setting up remote builders to get performant builds on resources constrained devices), as well as organizational annoyances (like having to clone this repo on every machine).
There seem to be a few projects to NixOS configurations including:
I’ve looked as NixOps as it’s the ‘official’ project. But the manual seems to suggest doing everything declaratively which is not ideal. (An aside, NixOps 1.7 fails to build due to a security issue and NixOps 2.0 is unstable, which is a bit daunting to a new user). There, however, does appear to be undocumented flake integration with nixopsConfigurations.
How are other people solving this problem? Is there a golden path?
One could probably make it nicer and get the list of hosts directly from the flake but for the moment it is good enough and allows me to focus on the servers themselves.
One thing which I still have to fix is limit password less sudo to the nix command but that isn’t something which is part of the script but part of the NixOS config.
FYI, nixos-rebuild supports remote builds via --target-host. You can run that from your repo and point nixos-config's NIX_PATH at some machine’s config; i.e. -I nixos-config=configs/machine/default.nix.
I’m not familiar with Cachix, but I think this is a bit too complicated for my use case. I wasn’t looking for a CI system but rather a script to way to deploy on remote machines. Thank you for the offer though!
One could probably make it nicer and get the list of hosts directly from the flake but for the moment it is good enough and allows me to focus on the servers themselves.
$ sudo nix build /etc/nixos#nixosConfigurations.rasp-pi.config.system.build.toplevel --builders 'ssh-ng://rasp-pi aarch64-linux' --max-jobs 0 builders-use-substitutes --option builders-use-substitutes true
# relies on $(readlink ./result) already being in the rasp-pi's nix store from using it as a remote builder
# it would be nice if there was a way to avoid having to copy this back to the workstation machine
$ ssh root@rasp-pi nix-env -p /nix/var/nix/profiles/system --set $(readlink ./result)
$ ssh root@rasp-pi /nix/var/nix/profiles/system/bin/switch-to-configuration switch
Ah I see you’re building on a remote system with different architecture while I build on localhost an x86_64-linux system configurations for aarch64-linux systems.