This article contains tips & tricks for using NixOS.contents…
Installing NixOS
This guide lays out how to install NixOS with an encrypted root and swap disk. The resulting system will have 2 physical partitions:
/boot
./dev/mapper/cryptroot
, an encrypted partition with 2 virtual partitions:/dev/vg/root
, mounted as /
./dev/vg/swap
, used for swap.
Physical partitions
First, determine if your machine supports UEFI (most modern PCs), or only has BIOS (e.g. my Thinkpad X201).
If it has UEFI, the below snippet creates a 512MiB UEFI boot partition, which has to be FAT32, and uses the rest of the disk for our cryptroot.
$ parted /dev/sda
> mklabel gpt
> mkpart ESP fat32 1MiB 512MiB
> set 1 boot on
> mkpart primary 512MiB 100%
> quit
For machines without UEFI, the procedure is similar, but needs to use BIOS and MBR formats.
$ parted /dev/sda
> mklabel msdos
> mkpart primary 1MiB 512MiB
> set 1 boot on
> mkpart primary 512MiB 100%
> quit
To set up LUKS disk encryption, first encrypt the second partition (/dev/sda2
), then unlock it and map it at /dev/mapper/cryptroot
:
$ cryptsetup luksFormat /dev/sda2
$ cryptsetup open /dev/sda2 cryptroot
Virtual Partitions
To split our LUKS-encrypted partition into two virtual partitions, we will use LVM to create a Physical Volume containing a Volume Group containing 2 Logical Volumes.
Create a Physical Volume (pv
):
$ pvcreate /dev/mapper/cryptroot
Create a Volume Group (vg
) on that pv
:
$ vgcreate vg /dev/mapper/cryptroot
Create two Logical Volumes (lv
) on that vg
, one for swap and one for data:
$ lvcreate -L 8G -n swap vg
$ lvcreate -l '100%FREE' -n root vg
For UEFI, format the boot partition as FAT32:
$ mkfs.fat -F 32 -n boot /dev/sda1
For BIOS / MBR, format the boot partition as EXT4:
$ mkfs.ext4 -L boot /dev/sda1
For both, format /
and the swap partition:
$ mkfs.ext4 -L root /dev/vg/root
$ mkswap -L swap /dev/vd/swap
Then mount them all:
$ mount /dev/vg/root /mnt
$ mkdir /mnt/boot
$ mount /dev/sda1 /mnt/boot
$ swapon /dev/vg/swap
Actually installing NixOS
We will need to make sure that our encrypted physical partition is unencrypted early in boot, so that the virtual partitions can be mounted.
Generate an initial configuration.nix
:
$ nixos-generate-config --root /mnt
The file /mnt/etc/nixos/hardware-configuration.nix
should reference the UUIDs for the physical /dev/sda1
and logical /dev/vg/root
and /dev/vg/swap
.
To mount the encrypted LVM partitions early in boot, we need to pass the UUID of the physical partition /dev/sda2
to initrd
. This can be found with ls -l /dev/disk/by-uuid
and seeing which UUID is pointing to /dev/sda2
:
$ ls -l /dev/disk/by-uuid
... b2bacfda-0929-43ef-9f8f-c326c41d9126 -> ../../sda1
... 4e906a20-63fc-4aec-93de-8502f24daa91 -> ../../sda2
... 97650361-78bc-4026-962d-0774fc388d63 -> ../../dm-1
... fa099f4f-38b8-4ebc-914c-86b11598128d -> ../../dm-2
This value must then be
$ cat /mnt/etc/nixos/configuration.nix
...
boot.loader.grub.device = "/dev/sda";
boot.initrd.luks.devices.root = {
device = "/dev/disk/by-uuid/4e906a20-63fc-4aec-93de-8502f24daa91";
preLVM = true; # we need to decrypt the physical partition before LVM mounts our logical partitions.
allowDiscards = true; # enables TRIM, optional.
};
Continue NixOS installation, rebooting after:
$ nixos-install
$ reboot
After rebooting, you will need to type your LUKS password, and it should boot normally from there on.
NixOS release process
- A PR is sent.
- The reviewer merges it into the
staging
branch. - The current
staging
is merged into the staging-next
branch for QA on Hydra. - A PR is created to merge
staging-next
into the master
branch (example). - Hydra churns, builds cache packages, etc.
- Hydra releases it to the
nixos-unstable
channel.
The status of the NixOS channels is on status.nixos.org.
nixos-unstable
vs nixpkgs-unstable
Both channels are from master
, but with different acceptance tests. Use nixos-unstable
.