Summary

In the previous post (Installing NixOS on BTRFS: Part 1) I realized only after installing NixOS that I had forgot to encrypt my installation, so I have decided to reinstall. This is a small follow up to that post.

Setting up the storage

Like before I opted for BTRFS RAID-0 with two 1TB NVME SSDs, and I made a small change, I will not be using a swap partition this time around. After some consideration I don’t see the value in adding swap to my HTPC system.

Order of operations

  1. Setup boot partition
  2. Setup bulk storage
  3. Setup BTRFS volumes
  4. Mount storage for installation
  5. Generate a hardware config file
  6. Merge new configuration into current
  7. Install

Setup boot partition:
First I setup just a very basic fat32 boot partition as usual.

parted /dev/disk/by-id/nvme-eui.0025385b0140445b -- mklabel gpt
parted /dev/disk/by-id/nvme-eui.0025385b0140445b -- mkpart ESP fat32 1MiB 1GiB
parted /dev/disk/by-id/nvme-eui.0025385b0140445b -- set 1 boot on
mkfs.vfat /dev/disk/by-id/nvme-eui.0025385b0140445b-part1

Setup bulk storage:
In this step I create the second partition, on the first device, and I create a single partition on the second device. After creating both partitions and their filesystems, I setup encryption on both using cryptsetup.

Note:
It’s possible that both devices could use different passwords, however setting the same password for both makes the boot process simpler. At boot the password will be tried automatically on the second device after the first one is unlocked.

After both devices have been encrypted and opened, they can be merged into a raid0 array, then mount one to /mnt.

# Setup bulk storage on first device
parted /dev/disk/by-id/nvme-eui.0025385b0140445b -- mkpart primary 1GiB 100%

# Setup second disk
parted /dev/disk/by-id/nvme-eui.0025385791b269cc -- mklabel gpt
parted /dev/disk/by-id/nvme-eui.0025385791b269cc -- mkpart primary 0% 100%

cryptsetup luksFormat --type=luks2 /dev/disk/by-id/nvme-eui.0025385b0140445b-part2
cryptsetup luksFormat --type=luks2 /dev/disk/by-id/nvme-eui.0025385791b269cc-part1
cryptsetup open /dev/disk/by-id/nvme-eui.0025385b0140445b-part2 device-1
cryptsetup open /dev/disk/by-id/nvme-eui.0025385791b269cc-part1 device-2

mkfs.btrfs -m raid0 -d raid0 /dev/mapper/device-1 /dev/mapper/device-2
mount -t btrfs -o rw,noatime,discard=async,compress-force=zstd /dev/mapper/device-1 /mnt

Setup BTRFS volumes:
With the BTRFS filesystems mounted, I create the subvolumes I intend on using, and then unmount /mnt.

btrfs subvolume create /mnt/nix
btrfs subvolume create /mnt/etc
btrfs subvolume create /mnt/log
btrfs subvolume create /mnt/root
btrfs subvolume create /mnt/home
umount /mnt

Mount storage for installation:
Now I mount /mnt as a tmpfs, and create directories that correspond to the subvolumes I made above, and mount each subvolume to its respective folder.

mount -t tmpfs -o mode=755 none /mnt
mkdir -p /mnt/{boot,nix,etc,log,root,home}
mount /dev/disk/by-id/nvme-eui.0025385b0140445b-part1 /mnt/boot
mount -o subvol=nix,rw,noatime,discard=async,compress-force=zstd /dev/mapper/device-1 /mnt/nix
mount -o subvol=etc,rw,noatime,discard=async,compress-force=zstd /dev/mapper/device-1 /mnt/etc
mount -o subvol=log,rw,noatime,discard=async,compress-force=zstd /dev/mapper/device-1 /mnt/log
mount -o subvol=root,rw,noatime,discard=async,compress-force=zstd /dev/mapper/device-1 /mnt/root
mount -o subvol=home,rw,noatime,discard=async,compress-force=zstd /dev/mapper/device-1 /mnt/home

Generate a hardware config file:
Because I am lazy I use nixos-generate-config to create a hardware-configuration.nix file.

nixos-generate-config --root /mnt

Merge new configuration into current:
Like before I copied the hardware-configuration.nix file off of the live system and merged it into my working configuration. After getting the hardware-configuration.nix file merged into my working config I needed to edit the file to add compress=zstd and discard=async to each mounted BTRFS volumes options, like below:

fileSystems."/home" =
 { device = "/dev/mapper/device-1";
   fsType = "btrfs";
   options = [ "subvol=home" "discard=async" "compress-force=zstd"];
 };

I also discovered I needed to add BOTH encrypted devices to the configuration file, this is obvious but I forgot to do so on my first install and this lead to a failure to boot. The nixos-generate-config command will only pick up on a single BTRFS device and therefor the second one needs to be added to the config manually.

boot.initrd.luks.devices."device-1".device = "/dev/disk/by-uuid/f9c027fa-2436-4e5e-ae1d-30847c9e80aa";
boot.initrd.luks.devices."device-2".device = "/dev/disk/by-uuid/3caa4b8f-e56a-45c3-ad17-17976eba6b92";

Install:
Finally I installed the system.

nixos-install

Sources