Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Minimal Btrfs-Subvol Install with Disko and Flakes

Disko allows you to declaratively partition and format your disks, and then mount them to your system. I recommend checking out the README as it is a disk destroyer if used incorrectly.

We will mainly be following the disko quickstart guide

If you have a ton of RAM you could most likely skip the minimal install and just set your system up as needed or just use tmpfs as root

  1. Get the Nixos Minimal ISO Get it on a usb stick, I use Ventoy with Ventoy2Disk.sh. The following is the link to the Ventoy TarBall download, untar it with tar -xzf ventoy-1.1.05-linux.tar.gz, and make it executable with chmod +x Ventoy2Disk.sh, and finally execute it with sudo bash Ventoy2Disk.sh Follow the prompts to finish the install.

  2. The minimal installer uses wpa_supplicant instead of NetworkManager, to enable networking run the following:

sudo systemctl start wpa_supplicant
wpa_cli
> add_network
0

> set_network 0 ssid "myhomenetwork"
OK

> set_network 0 psk "mypassword"
OK

> enable_network 0
OK

To exit type quit, then check your connection with ping google.com.

Another option is to do the following, so either the above method or the below method after starting wpa_supplicant:

# Alternative for quick setup (less interactive, but often faster)
sudo wpa_passphrase "myhomenetwork" "mypassword" >> /etc/wpa_supplicant/wpa_supplicant-wlan0.conf
sudo systemctl restart wpa_supplicant@wlan0.service
  1. Get your Disk Name with lsblk

The output should be something like:

NAME        MAJ:MIN RM   SIZE RO TYPE MOUNTPOINTS
nvme0n1     259:0    0   1,8T  0 disk
  1. Copy the disk configuration to your machine. You can choose one from the examples directory. I chose the btrfs-subvolumes layout so I ran the following:
cd /tmp
curl https://raw.githubusercontent.com/nix-community/disko/refs/heads/master/example/btrfs-subvolumes.nix -o /tmp/disk-config.nix
  1. Make Necessary changes, I set mine up for impermanence with the following:
nano /tmp/disk-config.nix
{
  disko.devices = {
    disk = {
      main = {
        type = "disk";
        device = "/dev/nvme0n1";
        content = {
          type = "gpt";
          partitions = {
            ESP = {
              priority = 1;
              name = "ESP";
              start = "1M";
              end = "512M";
              type = "EF00";
              content = {
                type = "filesystem";
                format = "vfat";
                mountpoint = "/boot";
                mountOptions = ["umask=0077"];
              };
            };
            root = {
              size = "100%";
              content = {
                type = "btrfs";
                extraArgs = ["-f"]; # Override existing partition
                # Subvolumes must set a mountpoint in order to be mounted,
                # unless their parent is mounted
                subvolumes = {
                  # Subvolume name is different from mountpoint
                  "/root" = {
                    mountpoint = "/";
                    mountOptions = ["subvol=root" "compress=zstd" "noatime"];
                  };
                  # Subvolume name is the same as the mountpoint
                  "/home" = {
                    mountOptions = ["subvol=home" "compress=zstd" "noatime"];
                    mountpoint = "/home";
                  };
                  # Sub(sub)volume doesn't need a mountpoint as its parent is mounted
                  "/home/user" = {};
                  # Parent is not mounted so the mountpoint must be set
                  "/nix" = {
                    mountOptions = [
                      "subvol=nix"
                      "compress=zstd"
                      "noatime"
                    ];
                    mountpoint = "/nix";
                  };
                  "/persist" = {
                    mountpoint = "/persist";
                    mountOptions = ["subvol=nix" "compress=zstd" "noatime"];
                  };
                  "/log" = {
                    mountpoint = "/var/log";
                    mountOptions = ["subvol=log" "compress=zstd" "noatime"];
                  };
                  "/lib" = {
                    mountpoint = "/var/lib";
                    mountOptions = ["subvol=lib" "compress=zstd" "noatime"];
                  };
                  # This subvolume will be created but not mounted
                  "/test" = {};
                };

              };
            };
          };
        };
      };
    };
  };
  fileSystems."/persist".neededForBoot = true;
  fileSystems."/var/log".neededForBoot = true;
  fileSystems."/var/lib".neededForBoot = true;
}
  • You may choose to add a swapfile to the above disk-config.nix, I haven't included it here because I manage it with the impermanence module. If you were to add it here you could just add under say the "/lib" section add:
# Persistent subvolume for swapfile
"/persist/swap" = {
  mountpoint = "/persist/swap";
  mountOptions = ["subvol=persist/swap" "noatime"]; # No compression for swap
};
fileSystems."/persist/swap".neededForBoot = true;
  1. Run disko to partition, format and mount your disks. Warning this will wipe EVERYTHING on your disk. Disko doesn't work with dual boot.
sudo nix --experimental-features "nix-command flakes" run github:nix-community/disko/latest -- --mode destroy,format,mount /tmp/disk-config.nix

Check it with the following:

mount | grep /mnt

The output for an nvme0n1 disk would be similar to the following:

/dev/nvme0n1p1 on /mnt type ext4 (rw,relatime,stripe=2)
/dev/nvme0n1p2 on /mnt/boot type vfat (rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro)
# ... snip ...
  1. Generate necessary files, here we use --no-filesystems because disko handles the fileSystems attribute for us.
nixos-generate-config --no-filesystems --root /mnt
sudo mv /tmp/disk-config.nix /mnt/etc/nixos
  1. Create the flake in your home directory, then move it to /mnt/etc/nixos
mkdir flake && cd flake
nix-shell -p git yazi helix
export NIX_CONFIG='experimental-features = nix-command flakes'
export EDITOR='hx'
hx flake.nix
# flake.nix
{
  description = "NixOS configuration";

  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
    inputs.disko.url = "github:nix-community/disko/latest";
    inputs.disko.inputs.nixpkgs.follows = "nixpkgs";
    # impermanence.url = "github:nix-community/impermanence";
  };

  outputs = inputs@{ nixpkgs, ... }: {
    nixosConfigurations = {
      hostname = nixpkgs.lib.nixosSystem {
        system = "x86_64-linux";
        modules = [
          ./configuration.nix
          inputs.disko.nixosModules.disko
          # inputs.impermanence.nixosModules.impermanence
        ];
      };
    };
  };
}

Move all the files into your flake:

cd /mnt/etc/nixos/
sudo mv disk-config.nix hardware-configuration.nix configuration.nix ~/flake
  1. Edit configuration.nix with what is required, the following is required, I clone my original flake repo and move the pieces into place but it's fairly easy to just type it all out:
  • Bootloader

  • User

  • Networking

  • hardware-configuration.nix & disk-config.nix for this setup

  • initialHashedPassword: Run mkpasswd -m SHA-512 -s, then enter your desired password. Example output,

Password: your_secret_password
Retype password: your_secret_password
$6$random_salt$your_hashed_password_string_here_this_is_very_long_and_complex

copy the hashed password and use it for the value of your initialHashedPassword

# configuration.nix
{
  config,
  lib,
  pkgs,
  inputs,
  ...
}: {
  imports = [
    # Include the results of the hardware scan.
    ./hardware-configuration.nix
    ./disk-config.nix
  ];

  networking.hostName = "magic"; # Define your hostname.

  networking.networkmanager.enable = true;

  boot.loader.systemd-boot.enable = true; # (for UEFI systems only)
  # List packages installed in system profile.
  # You can use https://search.nixos.org/ to find more packages (and options).
  environment.systemPackages = with pkgs; [
    vim # Do not forget to add an editor to edit configuration.nix! The Nano editor is also installed by default.
    #   wget
    git
  ];

  time.timeZone = "America/New_York";

  users.users.nixos = {
    isNormalUser = true;
    extraGroups = [ "wheel" "networkmanager" ]; # Add "wheel" for sudo access
     initialHashedPassword = "COPY_YOUR_MKPASSWD_OUTPUT_HERE"; # <-- This is where it goes!
    # home = "/home/nixos"; # Optional: Disko typically handles home subvolumes
  };

  console.keyMap = "us";

  nixpkgs.config.allowUnfree = true;

  system.stateVersion = "25.05"; # Did you read the comment?
}
  1. Move the flake to /mnt/etc/nixos and run nixos-install:
sudo mv ~/flake /mnt/etc/nixos/
sudo nixos-install --flake /mnt/etc/nixos/flake .#hostname
  • You will be prompted to enter a new password if everything succeeds.

  • If everything checks out, reboot the system and you should be prompted to enter your user and password to login to a shell to get started.

  • The flake will be placed at /etc/nixos/flake, I choose to move it to my home directory. Since the file was first in /etc you'll need to adjust the permissions with something like sudo chmod username:users ~/flake and then you can work on it without privilege esculation.

  • To continue following allong and set up impermanence Click Here