Converting Archlinux with BTRFS into NixOS

Posted on Sat 24 August 2024 in NixOS

Recently I have converted my laptop from Archlinux into NixOS without reformatting or plugging a USB live distro and kept my home partition as is. This was done from the existing Archlinux install.

The former system was installed on top a BTRFS root subvolume. I use that to my advantage. These steps are for NixOS specifically but in principle could be done with other distributions.

Former setup

The former setup is Arch installed on top of BTRFS with full disk encryption with systemd-boot (on EFI). Two subvolumes were used : root and home used respectively for / and /home/. The layout can be summarized by

$ lsblk
NAME         MAJ:MIN RM   SIZE RO TYPE  MOUNTPOINTS
zram0        253:0    0     8G  0 disk  [SWAP]
nvme0n1      259:0    0 476,9G  0 disk  
├─nvme0n1p1  259:1    0   512M  0 part  /boot
└─nvme0n1p2  259:2    0 476,4G  0 part  
  └─cryptdev 254:0    0 476,4G  0 crypt /home
                                        /
$ btrfs subvolume list /
ID 256 gen 2394 top level 5 path root
ID 257 gen 2394 top level 5 path home
(... some lines are omitted here)

The goal will be to create a new root subvolume for NixOS called nixos_root

Installing NixOS tools

First we need to get nix tools, this is done by installing nix the normal way.

$ sh <(curl -L https://nixos.org/nix/install) --daemon

Reopen the shell and install NixOS installation tools.

$ nix-channel --add https://nixos.org/channels/nixos-24.05 nixpkgs
$ nix-env -f '<nixpkgs>' -iA nixos-install-tools

Prepare environment

Just like a regular CLI install we are going to prepare /mnt/ to host the future system (which happens to be on the same disk as the current system). Please adapt the following steps to your disk layout :

$ mount /dev/mapper/cryptdev /btr_pool 
$ btrfs subvolume create /btr_pool/nixos_root
$ mount -o subvol=nixos_root,compress=zstd,ssd,space_cache=v2,noatime /dev/mapper/cryptdev /mnt
$ mkdir /mnt/home && mount -o subvol=home,compress=zstd,ssd,space_cache=v2,noatime /dev/mapper/cryptdev /mnt/home
$ mkdir /mnt/boot && mount /dev/nvme0n1p1 /mnt/boot

Install NixOS

First prepare the NixOS configuration files: * /mnt/etc/nixos/hardware-configuration.nix * /mnt/etc/nixos/configuration.nix

This is almost identical to a regular install of NixOS from an live NixOS environment. It just requires some path modification.

$ PATH="$PATH" NIX_PATH="$NIX_PATH" `which nixos-install` --root /mnt

You can now reboot to the new system. I had to run from the NixOS a command to make nix commands work. Basically update the channel files:

$ $nix-channel --update

In principle at boot time you should be able to choose between the old system (Archlinux) and the new system (NixOS). If you do keep both systems keep in mind NixOS might modify the location of files like ~/.bashrc.