Installing Guix

Have you ever been sold on the idea of immutable and reproducible systems? Have you ever used NixOS and, despite its awesomeness, felt that its programming language, Nix, is awkward and lacks elegance? Enter Guix, which uses Guile Scheme, a Lisp dialect, instead of Nix. The simplicity and elegance of Guile are what made me fall in love with Guix.

I use M series Mac machines, and sadly, Linux is not 100% supported on them. The next best thing is to install Guix on a virtual machine. Things would have been simple if Guix provided aarch64 installation images, but this is not the case—only x86-64 images are available. One would need to build an aarch64 image in order to run it on a virtual machine. In this post, I will detail how to build an aarch64 image tailored to run on VMWare Fusion for M series Mac machines.

The first step is to install any GNU/Linux distribution on the VM. In my case, I installed Ubuntu Server. It is pretty lightweight and yet serves our purpose. Make sure to create a partition of size at-most 5GB using the Ubuntu installation wizard. Next, we must install the Guix package manager. One way is to run the following commands as root.

cd tmp/
wget https://guix.gnu.org/install.sh
chmod +x guix-install.sh
./guix-install.sh

The second step is to update Guix. In particular, we update to the version at commit 49e42ea01e6182b95639b0bb9c62c887f7eda095. This is done via

sudo -i guix pull --commit=49e42ea

The idea now is to leverage the init sub-command of guix system to populate a separate partition with all the necessary files required for Guix installation. Once done, we boot from the said partition and start the Guix installation process in earnest.

To that end, we have already created a partition when we installed Ubuntu. As the third step, we label the partition using the command

sudo e2label /dev/nvme0n1p2 "Guix_image"

where I have assumed that /dev/nvme0n1p2 is the name of the new partition. Finally, we mount it to /mnt like so:

sudo mount /dev/nvme0n1p2 /mnt

Now to the fourth step. We create a Guile Scheme file, installation-image.scm, containing an operating-system declaration that defines the installation image we would like to populate on the previously mentioned disk.

(use-modules (gnu)
             (guix)
             (gnu system install))

(operating-system
 (inherit installation-os)
 (bootloader (bootloader-configuration
                (bootloader grub-efi-bootloader)
                (targets (list "/boot/efi"))))
 (initrd-modules (cons "nvme" %base-initrd-modules)))

The thing to note here is that we add the nvme kernel module to initrd. Without this, the installation image would fail to boot from our nvme disk.

Finally, in the last step, we execute the command below to populate the disk:

sudo $(type -P guix) system init /path/to/installation-image.scm /mnt

Exit the virtual machine, and create a new virtual disk. This where Guix is to be installed. Booting from nvme0n1p2 will run the Guix installation wizard.

../