Introduction
Recently I’ve been seeing a lot of coverage of NixOS on YouTube from my favorite Linux content creators, so I’ve decided to jump on the band wagon and check it out. For those that don’t know, NixOS is a linux distro that revolves around the Nix package manager. The main purpose of Nix is to provide reproducible and relible builds. Basically, think Terraform but for anything happening on your Linux system. NixOS takes this to the next level by allowing the user to configure everything relating to your OS in a configuration file! This file can then be moved to another system running NixOS, run a single command, and BOOM, a system that is identical to the other system.
Since I’m pretty particular as to how my system is partitioned and what filesystem I use, I decided to setup a LUKS-BTRFS-LVM install. I know there are libraries like disko, but I’ve decided to go through the initial install manually to get a better grasp of NixOS.
Partitioning
To start off with, this is the partitioning layout I’ve come up with:
/dev/nvme0n1p1 - 600M /boot/efi partition
/dev/nvme0n1p2 - 1G /boot parition
/dev/nvme0n1p3 (LUKS)
|_ 32GB swap LVM
|_ Rest of Drive root btrfs LVM
|_ @ (root)
|_ @home
|_ @nix (holds nix store)
|_ @persist (contants system state)
|_ @log (/var/log)
|_ @fresh (RO snapshot of @, used to clean darlings)
Setup
Create a new LUKS Partition and open it:
cryptsetup luksFormat /dev/nvme0n1p3 --label CRYPT
cryptsetup open /dev/nvme0n1p3 crypt
Initiate the LVM structure:
pvcreate /dev/mapper/crypt
vgcreate vg /dev/mapper/crypt
Create a parition for the swap and root:
lvcreate -L 32G -n swap vg
lvcreate -l '100%FREE' -n root vg
Format the partitions:
mkswap -L swap /dev/vg/swap
mkfs.btrfs /dev/vg/root
Btrfs
Create the subvolumes for the root partition:
mount /dev/vg/root /mnt
btrfs subvolume create /mnt/@
btrfs subvolume create /mnt/@home
btrfs subvolume create /mnt/@nix
btrfs subvolume create /mnt/@persist
btrfs subvolume create /mnt/@log
Create a Read-Only snapshot of root subvolume:
btrfs subvolume snapshot -r /mnt/@ /mnt/@fresh
umount /mnt
Mount the partitions and subvolumes:
mount -o compress=zstd,subvol=@ /dev/vg/root /mnt
mkdir -p /mnt/{home,nix,persist,var/log,boot}
mount -o compress=zstd,subvol=@home /dev/vg/root /mnt/home
mount -o compress=zstd,noatime,subvol=@nix /dev/vg/root /mnt/nix
mount -o compress=zstd,subvol=@persist /dev/vg/root /mnt/persist
mount -o compress=zstd,subvol=@log /dev/vg/root /mnt/var/log
mount /dev/nvme0n1p2 /mnt/boot
mkdir -p /mnt/boot/efi
mount /dev/nvme0n1p1 /mnt/boot/efi
swapon /dev/vg/swap
Generate the configuration:
nixos-generate-config --root /mnt
By default, NixOS doesn’t recognize LUKS devices, so we need to add the following in the hardware-configuration.nix
:
boot.initrd.luks.devices = {
luksroot = {
device = "/dev/disk/by-uuid/THE_UUID_OF_THE_LUKS_PARTITION";
preLVM = true;
allowDiscards = true;
};
};
The mount options for the filesystems are not detected automatically by the NixOS installer, so we need to add the following:
fileSystems."/" =
{
options = [ "subvol=@" "compress=zstd" ]; # Options should look like this
};
fileSystems."/nix" =
{
options = [ "subvol=@nix" "compress=zstd" "noatime" ]; # Or This
};
Installation
Finally, its time to install NixOS
nixos-install
reboot