Preventing flake.nix written for remote targets from being garbage collected

I manage configurations of NixOS-based home servers with nix flake, using commands like nix run .#nixos-rebuild -- switch --flake '.#pi' --target-host root@pi.

Can I prevent those from being garbage collected? nix-collect-garbage deletes packages built for remote targets as garbage because they are not used in my main machine. It takes some time to build all packages from scratch (nix builds them even when they are already present on target machines), so I want to avoid that.

Run nixos-rebuild build --flake .#pi before nixos-rebuild switch.

This will create a ./result symlink to the built configuration, which is a GC root.

1 Like

You could write yourself a wrapper, that instead of a flake-ref takes just the “name” and would build something for you, including a GC-root to be created:

#!/usr/bin/env bash

nixos-rebuild build  --flake .#$1 --outlink ./result-$1
nixos-rebuild switch --flake .#$1 --target-host root@$1

Improvements might be possible or necessary, this is a quick writeup on a mobile…


My little example of how I am solving probably the same thing as you. I am not using nixos-rebuild at all and just building nixos system directly with my script. Feel free to inspire yourself. It has one nice feature compared to nixos-rebuild and that is it shows changes before it activates the new profile.

The entry string for remote hosts is here and implementation here.

It works exactly the same way as was suggested here already. It builds the system locally and outputs link to .result-HOST and thus it won’t be garbage collected. You might also consider setting keep-derivations as it prevents removal of build dependencies on garbage collection (handy for architectures not well supported by hydra).

Here is the shortened taste of the update of one of my router:

$ ./ bs dean
Building system for device: dean
Free space on device: 5.5G
Required space: 1.8G
Copy closure to: dean
copying path '/nix/store/1q0frwafz2xh27vxfly7bkwm05c9ff6w-bash-completion-aarch64-unknown-linux-gnu-2.11' from ''...
copying path '/nix/store/68zqb88azs961s0273i9w2b77zs77pv2-bash-interactive-5.2-p15-aarch64-unknown-linux-gnu-doc' from ''...
copying path '/nix/store/9i1qd3qaajqdx2lx01bzppkhj47pyd9j-audit-disable' from ''...
copying path '/nix/store/4d150dlifrxf8l3f985w5m7kvznnmjlb-audit-stop' from ''...
Switch system: dean
88ka726xr3l7ppkhxyg2r12hzp15vrrw: ε → ∅, -137.1 KiB
aws-c-io-aarch64-unknown-linux-gnu: 0.13.11 → 0.13.12
bash: 5.1-p16, 5.1-p16-aarch64-unknown-linux → 5.2-p15, 5.2-p15-aarch64-unknown-linux, +322.3 KiB
bash-interactive: 5.1-p16-aarch64-unknown-linux, 5.1-p16-aarch64-unknown-linux-gnu → 5.2-p15-aarch64-unknown-linux, 5.2-p15-aarch64-unknown-linux-gnu, +1028.6 KiB

@raphi Thanks. I needed to remove --target-host option when running nixos-build, otherwise result symlink won’t get created.
@NobbZ Would be better than typing 2 commands, though I can’t find --outlink option in nixos-rebuild. Maybe changing the name for result symlink is not supported on nixos-rebuild?

Cynerd 's script also looks interesting, I’ll try it later on.