Multi OS Disko Setup - Fedora and NixOS w/ Btrfs Subvolumes

Hey guys! I’ve been working on something pretty cool that could inspire some other interesting setups.
A second set of eyes would be greatly appreciated.
I am trying to install fedora and nixos on the same machine, but keep them separated.
The goal is to limit the amount of partitions since I want to size change dynamically.
Swap, preferably encrypted for hibernation is preferred.
In order to keep NixOS and Fedora separate I decided to use unique mounts for each.
I chose LUKS to encrypt the whole btrfs partition.
This was the layout and setup I ended up going with.

Partition Size OS Type
/boot 1 Gb Shared fat32
/swap 32 Gb Shared subvolume
/ ~ Shared btrfs
/nix/store ~ NixOS subvolume
/ (Fedora Root) ~ Fedora subvolume
/ (NixOS Root) ~ NixOS subvolume
/home/Shared ~ Shared subvolume

The plan here is for the NixOS install to not mount the fedora root, and for the Fedora install to not mount the NixOS root or the nix store.
I wrote a disko config below but I feel like I am missing something.
In the swap example, there was a presence of an unencrypted swap but I am uninterested in that, is it alright to setup up the encrypted swap without the other as I have done below?

{
  disko.devices = {
    disk = {
      main = {
        type = "disk";
        device = "/dev/nvme0n1";
        content = {
          type = "gpt";
          partitions = {
            ESP = {
              size = "1G";
              type = "EF00";
              content = {
                type = "filesystem";
                format = "vfat";
                mountpoint = "/boot";
                mountOptions = [ "umask=0077" ];
              };
            };
            encryptedSwap = {
              size = "32G";
              content = {
                type = "swap";
                randomEncryption = true;
                priority = 100; # prefer to encrypt as long as we have space for it
              };
            };
            luks = {
              size = "100%";
              content = {
                type = "luks";
                name = "crypted";
                # disable settings.keyFile if you want to use interactive password entry
                #passwordFile = "/tmp/secret.key"; # Interactive
                settings = {
                  allowDiscards = true;
                  keyFile = "/tmp/secret.key";
                };
                additionalKeyFiles = [ "/tmp/additionalSecret.key" ];
                content = {
                  type = "btrfs";
                  extraArgs = [ "-f" ];
                  subvolumes = {
                    # this should only be mounted if on fedora
                    # how do i not mount this automatically
                    "root_fedora" = {
                      mountpoint = "/";
                      mountOptions = [
                        "compress=zstd"
                        "noatime"
                      ];
                    };
                    # this should only be mounted if on nixos
                    "root_nixos" = {
                      mountpoint = "/";
                      mountOptions = [
                        "compress=zstd"
                        "noatime"
                      ];
                    };
                    # shared contents between fedora and nixos
                    "shared" = {
                      mountpoint = "/home/Shared";
                      mountOptions = [
                        "compress=zstd"
                        "noatime"
                      ];
                    };
                    "/nix" = {
                      mountpoint = "/nix";
                      mountOptions = [
                        "compress=zstd"
                        "noatime"
                      ];
                    };
                  };
                };
              };
            };
          };
        };
      };
    };
  };
}

NixOS Search says that randomEncryption should not be used for hibernation, and disko’s option maps directly to it.

I put my swap in luks, or luks contains lvm and lvm contains btrfs & swap.

If you don’t want to mount fedora’s root subvolume, just don’t specify mountpoint for it. Disko will create it, but won’t mount (reference).

All the examples I’ve seen use ‘/’ at start of subvolume names (e.g. root_nixos would be /root_nixos). Not sure if it’s a custom or requirement. The initial / still refers to root of FS, not mountpoints - I have a btrfs with mountpoint = '/mnt/real_root' and subvolumes declared as e.g. /home/current = { mountpoint = '/home';}. Said subvolume is visible both at /home (due to it’s mountpoint) and at /mnt/real_root/home/current (due to contatenation of FS’ mountpoint and subvolue’s path).

Thanks for catching the mount point thing, I thought I fixed that before I posted the blog.

I got lazy and made the swap unencrypted.
I’m going to try the LUKS way when I muster up the strength. In terms of mount points, this example here shows rootfs being set to “/” for a subvolume.

indeed it does, but that’s not what I had in mind. I mean keys to the subvolumes attrset. You have /nix = {...} which should be ok, but also root_fedora = {...} and others without leading /. I’m nit saying it won’t work, I’ve just never seen it work and never tried myself.

I changed it to match, I had an issue where I was missing a BIOS partition which prevented grub from installing, but after that everything is working.
I am going to share the updated setup before closing the discussion, thanks for the help.

Just incase you are curios here is a working disko setup that aligns w/ what I was trying to do


{
  disko.devices = {
    disk = {
      main = {
        type = "disk";
        device = "/dev/nvme0n1";
        content = {
          type = "gpt";
          partitions = {
            ESP = {
              size = "6G"; # just incase we use some ukis
              type = "EF00";
              content = {
                type = "filesystem";
                format = "vfat";
                mountpoint = "/boot";
                extraArgs = [ "-nEFI" "-F32" ];
                #mountOptions = [ "umask=0077" ];
              };
            };
            luks = {
              size = "100%";
              content = {
                type = "luks";
                name = "crypted";
                extraOpenArgs = [ ];
                settings = {
                  allowDiscards = true;
                };
                content = {
                  type = "lvm_pv";
                  vg = "pool";
                };
              };
            };
          };
        };
      };
    };
    lvm_vg = {
      pool = {
        type = "lvm_vg";
        lvs = {
          # partitions here
          # swap
          swapfs = {
            size = "32G";
            content = {
              extraArgs = [ "-L SWAPPY" ];
              type = "swap";
              resumeDevice = true;
            };
          };
          # btrfs w/ main stuff
           os_2 = {
            size = "100%";
            content = {
              type = "btrfs";
              extraArgs = [ "-f" "-L BURRO" ];
              subvolumes = {
                # this should only be mounted if on nixos
                "/root_nixos" = {
                  mountpoint = "/";
                  mountOptions = [
                    "compress=zstd"
                    "noatime"
                  ];
                };
                "/root_second" = {
                  #mountpoint = "/";
                  # mountOptions = [
                  #   "compress=zstd"
                  #   "noatime"
                  # ];
                };
                #shared contents between fedora and nixos
                "shared" = {
                  mountpoint = "/home/Shared";
                  mountOptions = [
                    "compress=zstd"
                    "noatime"
                  ];
                };
                "/nix" = {
                  mountpoint = "/nix";
                  mountOptions = [
                    "compress=zstd"
                    "noatime"
                  ];
                };
              };
            };
          };
        };
      };
    };
  };
}

I ended up adding some LUKS in there too.
Ig an updated partition description would be
A Dual Boot Setup for Debian and NixOS

Where there is an EFI partition for both OS’s and Kernel Images
LVM on LUKS partition holding a pool of BTRFS and Swap.
Where BTRFS is has subvolumes for the two operating systems and 1 shared mount.