If you're a NixOS user, you've probably wanted to partition your disk declaratively at some point.
Well, worry no more. With the disko NixOS module, you can do just that!
NB: this guide is based on disko as of commit 725ea35, make sure to check if any breaking changes have been made since this was published.
This guide assumes you're using flakes, as do about 78.9% of Nix users.
To start, you'll want to add disko to your flake's imports.
{
imports = {
# ...
disko = {
url = "github:nix-community/disko";
inputs.nixpkgs.follows = "nixpkgs";
};
};
}
Then, create a new Nix file where you'll configure your disk.
Disk layouts are defined in the disko.devices.disk.<name> attrset.
Let's define a basic disk:
{
disko.devices.disk = {
main = { # i'm calling my disk 'main', but you can call it whatever.
device = "/dev/disk/by-id/ata-FOOBAR_BAZQUX12345";
type = "disk";
content = {};
};
};
}
Notice that I used the /dev/disk/by-id/* path for my disk. This is important, as the /dev/sd* path can change depending on the order in which the kernel detects your disks. It's best to use the by-id path to prevent your system from failing to boot if you add or remove a drive, or the kernel just randomly detects one disk before the other.
Now, let's add some partitions.
{
disko.devices.disk = {
main = { # i'm calling my disk 'main', but you can call it whatever.
device = "/dev/disk/by-id/ata-FOOBAR_BAZQUX12345";
type = "disk";
content = {
type = "gpt";
partitions = {
ESP = { # create the efi partiation
type = "EF00";
size = "500M"; # explicitly set the size
content = { # set its filesystem
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
mountOptions = [ "umask=0077" ];
};
};
};
root = { # make the root partition
size = "100%"; # fill the rest of the disk
content = { # and set the filesystem
type = "filesystem";
format = "ext4";
mountpoint = "/";
};
};
};
};
};
}
Now, we need to make sure that our configuration loads the disko module.
Go back to your flake.nix file and import it.
{
# ...
outputs = inputs: {
nixosConfigurations.foobar = input.nixpkgs.lib.nixosSystem {
# ...
modules = [
# ...
inputs.disko.nixosModules.default # <-- import the module here
./disko.nix # don't forget to include the disko configuration file
];
};
};
}
Then, make sure to remove any disk info from hardware-configuration.nix to prevent it from conflicting with disko.
Now, let's use the disko-install tool to wipe our disk and install our config!
First, drop into a shell with the command available.
sudo nix run 'github:nix-community/disko/latest#disko-install' -- --flake <flake-url>#<flake-attr> --disk <disk-name> <disk-device>
nix shell github:nix-community/disko/latest#disko-install
Then, let's install NixOS with our Disko config!
NOTE THIS WILL WIPE EVERYTHING ON THE TARGET DRIVE.
sudo disko-install --write-efi-boot-entries --flake .#foobar --disk main /dev/disk/by-id/ata-FOOBAR_BAZQUX12345
# ^ adds entries to bootloader ^ hostname ^ ^ in `disko.devices.disk.<name>.device`
# |
# what you named the disk
# : in `disko.devices.disk.<name>`
Reboot, and there you go.
If you need a more advanced configuration, like LVM with full-disk encryption, RAID arrays with mdadm, BTRFS with subvolumes, etc. then you should check out the examples directory.
Below is my personal configuration, with a LUKS-encrypted root partition.
{
disko.devices = {
disk.main = {
type = "disk";
device = "/dev/disk/by-id/ata-ST1000LM035-1RK172_WDEHTZNN";
content = {
type = "gpt";
partitions = {
ESP = {
size = "500M";
type = "EF00";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
mountOptions = [ "umask=0077" ];
};
};
luks = {
size = "100%";
content = {
type = "luks";
name = "nixos";
settings.allowDiscards = false;
content = {
type = "filesystem";
format = "ext4";
mountpoint = "/";
};
};
};
};
};
};
};
}
I hope you found this short guide useful, and happy partitioning!
subscribe: atom rss