Partitioning NixOS with Disko
Published: 2024-03-27 • Reading time: 6 min
#linux #nixos #disko #sysadminAbout a month ago I decided to spend my free time getting more familiar with NixOS. In order to install NixOS, I needed to figure out what Linux Partitioning scheme I would use. Rather than manually partitioning, I decided I would dive straight into learning Disko the declarative disk partitioning system.
Diving into Disko ended up being quite an adventure, as I suspect much of my exploration of NixOS will be. I'm not content to simple type magic incantations into a configuration file, but rather I want to know what each magic incantation does. Let me share with you my journey, what I've learned so far, and my Disko configuration.
Exploring NixOS seems to be deeply rooted in "mess around and find out." There's a common thread across the Internet that NixOS documentation is lacking, especially when compared to Arch Linux which mostly has outstanding documentation. Fortunately, messing around and finding out seems to be a pretty normal pattern for me to learn new things and something I mostly enjoy.
Still, I can't decide if the time I'm investing in trying to figure out how Disko works for partitioning is worth the investment. I could have just used parted
, pvcreate
, vgcreate
, lvcreate
, mkfs
and been done already.
Building my Disko Configuration
In my initial exploration of the example configurations in the Disko git repository I can't shake the feeling that there's quite a bit of TIMTOWTDI (There Is More Than One Way To Do It, the reason why Perl scripts are so easy to write and so difficult to read) with Disko configuration. Is there an advantage to using start
and end
when specifying partitions, or is size
good enough. I'm not sure I care about the start and end assuming Disko is smart enough to align the partitions.
I ended up diving into the Disko source code to get a better feel for the differences between start
, end
, and size
. Here I discovered my first surprise: Disko is written in the Nix language. It felt like a moment where I discovered it's "turtles all the way down."
As I dug through the source I ran into a valuable comment from /lib/types/table.nix
: The legacy table
is outdated and should not be used. We recommend using the gpt
type instead. This helped invalidate various Disko configurations I was looking at that were still using table
.
As I continued to scan the source code I was particularly interested in how Disko would handle LVM configuration, as I had already decided that I would be using LVM as part of my partition configuration. Disko has a type for lvm_pv
and lvm_vg
but not lvm_lv
. Within lvm_vg
there's an lvs
item where you specify your logical volumes.
As a reminder, my partition scheme:
/dev/sda1 -- /boot, 1 GB, FAT32
/dev/sda2 -- (LVM vg1), the rest, LVM
- /dev/vg1/swap -- (swap), 8G, swap
- /dev/vg1/nix -- /nix, 50G, ext4
- /dev/vg1/root -- /, the rest, ext4
Based on the above, I was able to build the Disko configuration below:
{
disko.devices = {
disk.sda = {
type = "disk";
device = "/dev/sda";
content = {
type = "gpt"; # Initialize the disk with a GPT partition table
partitions = {
ESP = { # Setup the EFI System Partition
type = "EF00"; # Set the partition type
size = "1000M"; # Make the partition a gig
content = {
type = "filesystem";
format = "vfat"; # Format it as a FAT32 filesystem
mountpoint = "/boot"; # Mount it to /boot
};
};
primary = { # Setup the LVM partition
size = "100%"; # Fill up the rest of the drive with it
content = {
type = "lvm_pv"; # pvcreate
vg = "vg1";
};
};
};
};
};
lvm_vg = { # vgcreate
vg1 = { # /dev/vg1
type = "lvm_vg";
lvs = { # lvcreate
swap = { # Logical Volume = "swap", /dev/vg1/swap
size = "8G";
content = {
type = "swap";
};
};
nix = { # Logical Volume = "nix", /dev/vg1/nix
size = "50G";
content = {
type = "filesystem";
format = "ext4";
mountpoint = "/nix";
mountOptions = [
"noatime" # Reduce writes--we don't care about access times
];
};
};
root = { # Logical Volume = "root", /dev/vg1/root
size = "100%FREE"; # Use the remaining space in the Volume Group
content = {
type = "filesystem";
format = "ext4";
mountpoint = "/";
mountOptions = [
"defaults"
];
};
};
};
};
};
};
}
How to run Disko
The configuration file alone isn't enough to get the partitions created. You've got to actually run Disko.
- First, you need to boot up the NixOS installer.
- I stored my
disko-config.nix
as a gist on GitHub. Seemed like as good as place as any to host it. - I created a TinyURL shortcut for that link because there's no way I'm going to attempt to type that whole URL.
- Download the file using
curl
. Switch-L
will follow redirects,-o
specifies the file to store the output. My URL is a direct link raw disko-config.nix from GitHub.curl -L <url> -o /tmp/disko-config.nix
- Run disko:
sudo nix --experimental-features "nix-command flakes" run github:nix-community/disko -- --mode disko /tmp/disko-config.nix
- There's a couple of modes
--mode disko
will unmount and destroy all filesystems on the disks we want to format before creating and mounting our filesystems specified in the config file--mode format
will create partition tables, logical volumes, and filesystems--mode mount
will mount the partition at the specified root-mountpoint- I'm not sure when the
format
andmount
options are useful. I didn't try either.
- Complete the NixOS install
nixos-generate-config --no-filesystems --root /mnt
- The
--no-filesystems
switch is used because we're defining the filesystems in disko-config.nix.
- The
cp /tmp/disko-config.nix /mnt/etc/nixos
- Copy our disko config to the future /etc/nixos directory.
- Edit
/mnt/etc/nixos/configuration.nix
to add thedisko
NixOS module and ourdisko-config.nix
file to the imports section:
imports =
[
./hardware-configuration.nix
"${builtins.fetchTarball} "https://github.com/nix-community/disko/archive/master.tar.gz"}/module.nix"
./disko-config.nix
];
- And finally:
- Edit additional options in
/mnt/etc/nixos/configuration.nix
:networking.hostName
networking.networkmanager.enable
time.timeZone
environment.systemPackages
Don't forget to install an editor!
- Execute the install
nixos-install
reboot
- Edit additional options in
This is a fine first step into NixOS and Disko but there's more to learn about getting a system off the ground with Flakes. But that's a story for another day.