AlderAutomation

NixOS Dual Booting (Sort Of)

Last updated: 1 day, 12 hours ago

Intro

Recently, I had the idea, "Why can't I run two Linux flavours on my NixOS laptop?" Well I can and now I am!

I am not dual booting. I am using two separate config files to give me a GNOME setup in one generation and a terminal-only environment in another generation. This gives me two completely different NixOS environments while using the same drive and user settings and files, but not requiring partitioning of the drive and two full-fledged distro installs. The Insanity of it!

Note: this is for traditional non-flake NixOS

How It Works

I have one configuration file named gnome.nix. In it, I have all the required packages to run GNOME and I import the 'common.nix'. Then I have another file called terminal.nix, this one has all the terminal-only packages and also imports the 'common.nix'. And then I have a third config file called common.nix, and this one has packages and configs that are common to both configurations.

To import that common.nix config file, we add it to the imports section of each GNOME and Terminal config files:

  imports =
    [ # Include the results of the hardware scan.
      ./hardware-configuration.nix
      ./common.nix
    ];

My first thought was how do I tell them apart on the generation selection screen? NixOS has already thought of that: system.nixos.label = "TERMINAL";
This adds TERMINAL to the generation listing during boot time. I set one config to TERMINAL and the other to GNOME.

PXL_20261103_201111018

Ok, so the next problem is how do I build one or the other when I need to. Of course, NixOS already has figured that out as well with a -I flag that allows you to specify the build:
sudo nixos-rebuild boot -I nixos-config=/path/to/config/file.nix

After that, I bound that command to easy-to-remember rebuild command for each build file, and put it in my common config file as an alias:

  environment.shellAliases = {
    rebuild-gnome = "sudo nixos-rebuild boot -I nixos-config=/etc/nixos/gnome.nix";
    rebuild-terminal = "sudo nixos-rebuild boot -I nixos-config=/etc/nixos/terminal.nix";
  };

I chose to go with the boot flag because it's ... "safer" as an alias. I don't always know when I need boot vs switch, so if the alias is boot then I know it's always build and reboot to get changes. And I don't need two more aliases for switch command rebuilds. It comes down to being lazy and making it easy and predictable.

Side Effects and Gotchas

An interesting caveat to this method is that "sudo nix-collect-garbage -d" will remove all generations beyond the one you are currently on. Meaning if you are on GNOME, your terminal generation will be wiped out and you will need to rebuild it again. Of course, with the alias that we set up, this isn't that hard to do.

A couple of things that seem obvious but messed with my head for a bit:

Conclusion

Now I can build and boot from either file I want and I just wanted to share that and document it for future me.
Oh, the reason I chose GNOME and terminal as my two flavors:

If you want me to elaborate on anything, please message me on Discord, Mastodon, X, or email me. I’ll be happy to go into more detail one-on-one or to create more posts.

noaibadge

#NixOS #blog