Channels and `nixos-rebuild --target-host`

I’ve installed Nix in single-user mode on a my laptop (Fedora 39).

user@laptop:~$ nix --version
nix (Nix) 2.18.1

user@laptop:~$ nix-channel --list
nixpkgs https://nixos.org/channels/nixos-23.11

I’ve also a raspberrypi 3 (rpi3) with nixos 23.11 installed on it.

[root@nixos-rpi:~]# nixos-version 
23.11.3920.25e3d4c0d359 (Tapir)

[root@nixos-rpi:~]# nix-channel --list
nixos https://channels.nixos.org/nixos-23.11

My use-case is: I want to build the nixos rpi3 system on my laptop and push it to the rpi3. To do it, I use a the following command on my laptop:

user@laptop:~$ nixos-rebuild --target-host nixos-rpi.local \
                             -I nixos-config=./path/to/configuration.nix \
                             switch

Everything is working as expected. But I’ve a few questions:

  • how to keep my laptop Nix installation up to date?
  • how to keep the nixos system installed on the rpi3 up to date?

For the former question, is it sufficient to run the following commands?

user@laptop:~$ nix-channel --update
user@laptop:~$ nix-env --install --attr nixpkgs.nix nixpkgs.cacert nixpkgs.nixos-rebuild

For the last question, I don’t understand which channel is used by the nixos-rebuild command. When the nixos-rebuild command is executed, does it use the channel on my laptop or on the rpi3? Where should I run the nix-channel --update command?

Unless you are intentionally updating only those three packages, you would probably prefer:

user@laptop:~$ nix-channel --update
user@laptop:~$ nix-env --upgrade

(Obligatory Stop using nix-env. link.)

Channels contain the definitions of packages. nixos-rebuild needs a definition of packages in order to generate a closure which it then optionally ships off to a target machine for activation. So it will use the channel on your laptop; the channel on your target system is only used if you run Nix package-management commands there (and if you don’t do that, you can save space by removing it).

1 Like

Thanks for the link.

Can you confirm that I can’t use declarative package management with the Nix installation on my laptop? If I don’t get your link wrong, declarative package management requires NixOS (or Home Manager), which I’m not using to manage Nix packages on my laptop.

Ok, makes sense. But your answer bring some more questions to my mind :slight_smile:

What if I’ve 2 remote hosts, one using channel nixos-23.11 and the other nixos-23.05? Is it possible to generate a closure for each remote host on my laptop? If yes, how should I do it?

I already know that I’ll need to pick some packages from nixos-unstable on my rpi3 (which is using nixos-23.11). I’ve done some tests with this nix file imported in configuration.nix:

{ config, pkgs, ... }:

let
  unstable = import <nixos-unstable> {};
in {
  environment.systemPackages = with pkgs; [
    unstable.mox
  ];
}

And then I execute nixos-rebuild with:

user@laptop:~$ nixos-rebuild --target-host nixos-rpi.local \
                             -I nixos-unstable=channel:nixos-unstable \
                             -I nixos-config=./path/to/configuration.nix \
                             switch

It works, but I don’t understand why as I’ve not added the nixos-unstable channel on my laptop.

Home Manager is great and you should use Home Manager. Despite the name, it doesn’t take control over any part of your home that you don’t tell it to take over. If all you do with Home Manager is specify a list of home.packages, it’ll declaratively install those packages and leave the rest of your dotfiles and services for you to manage as you always have. Use Home Manager.

If for some reason you read the above and don’t want to use Home Manager, reconsider. Then, if you still haven’t seen the light, the Declarative Package Management section of the Nixpkgs manual will get you mostly off of nix-env.

Just like with your later example, nixos-rebuild -I is the key. Use either -I nixpkgs=channel:nixos-23.11 or -I nixpkgs=channel:nixos-23.05, as needed.

Are you sure you haven’t? What’s the output of nix-channel --list on your laptop?

1 Like

Ok, I’ll give it a try.

Yep. I’ve checked again, but only channel “nixos-23.11” is listed:

user@laptop:~$ nix-channel --list
nixpkgs https://nixos.org/channels/nixos-23.11

Question: is it normal that I’m using a channel named “nixpkgs” on my laptop and “nixos” on my rpi3? Both names are for the same channel https://channels.nixos.org/nixos-23.11.

Anyway, I’ve run nixos-rebuild with the --verbose flag, and at some point in the output I see that the “nixos-unstable” channel is downloaded:

downloading 'https://nixos.org/channels/nixos-unstable/nixexprs.tar.xz'...

Next runs of nixos-rebuild don’t show this message. I guess there is some sort of cache to avoid downloading the channel every time.

That could explain why it works even if the “nixos-unstable” channel was not added with nix-channel --add ....

Yeah, that’s normal. I think that if you look at the $NIX_PATH environment variable on the Raspberry Pi you’ll see that it points nixpkgs to a profile link named nixos.

Oh, that’s right! The channel: syntax in --include options actually fetches a recent tarball directly, bypassing the things nix-channel has done. That’s documented here, but only for the new nix commands, even though it would seem to apply to the non-experimental commands as well.

1 Like