One single configuration for multiple architectures

Hi. I’m new to NixOS and I would like to have only one configuration for all my systems.
I’ve got a “normal” x86-64 computer and a Raspberry Pi, I’d like NixOS to automatically select the correct boot configuration based on the architecture, is there a way to do that, possibly taking advantage of Flakes? Thank you :slight_smile:

Yes, this is possible! Flakes are potentially useful for this, but actually you don’t really need them.

You can just put your configuration.nix file on the raspberry pi as well and install it just like you did on your big computer.
If you need to change some smaller things depending on the architecture (because maybe some package is not available on ARM), you can always check the value of pkgs.system.

Do you have a repo with your current configuration? It’s always easiest to explain things directly in your code that you’re familiar with.

No, I don’t currently have any repo (but you can find my config on gists My NixOS config · GitHub)…I was just experimenting adapting some snippets I had found. In particular in order to make the system boot on the RPi you need to add some additional configuration that i marked with comments.

Ah ok. So what you could do in theory if you only care about these two cases (raspberry pi and computer) is to take pkgs.system and use that to decide on those options. The basic syntax for this would be like this:

{ config, pkgs, ...}:

{
  # All the options you want to have on ALL machines
  boot = if pkgs.system == "aarch64-linux" then {
    # Raspberry Pi boot config
  } else {
    # Main computer boot config
  };
}

However, this quickly becomes difficult to maintain, as you’re copying the same condition at multiple locations.

So a better solution is to use the imports array. You’re already linking to a hardware-configuration.nix, so you can see how that works. In addition, you could create a pc-configuration.nix and raspi-configuration.nix which contain everything that’s specific to those systems.
Then in your configuration.nix you can use them like so:

{ config, pkgs, ... }:

{
  imports =
    [ 
      ./hardware-configuration.nix
    ] ++ 
      if pkgs.system == "aarch64-linux" then
        [ ./raspi-configuration.nix ]
      else
        [ ./pc-configuration.nix ]
     ;
  # then comes the rest of your configuration.nix
}

The issue with this solution is that you’ll start having trouble if you set up more machines. This is where flakes become very useful.

You can write a /etc/nixos/flake.nix like this:

{
  outputs = { self, nixpkgs, ... }: {
    nixosConfigurations = {
      pamplemousse = nixpkgs.lib.nixosSystem {
        system = "aarch64-linux";
        modules = [
          ./configuration.nix
          ./raspi-configuration.nix
          { networking.hostname = "pamplemousse"; }
        ];
      };
      myComputer = nixpkgs.lib.nixosSystem {
        system = "x86_64-linux";
        modules = [
          ./configuration.nix
          ./pc-configuration.nix
          { networking.hostname = "mycomputer"; }
        ];
      }
    };
  };
}

You can just add more entries to nixosConfigurations for every machine you have.

The nice thing is that nixos-rebuild will automatically use the hostname of the current system to decide which configuration to use.

Is this enough info to get you started?

1 Like

Yess, thanks a lot. Would you please link me some places where I could find more informations?

The “Using flakes with NixOS” section of the NixOS Wiki Flakes page is a good starting point :slight_smile:

You may also want to have a look at the NixOS manual section “Configuration Syntax”. It’s a little long, but contains pretty much all the info you need.

1 Like