Prepare Installation Media

  • Download the latest Arch ISO
  • Write image to a USB media
  1. Linux

Simply use the dd command to write the ISO to the drive

sudo dd if=<Path to ISO> of=<Target Device> bs=4096 status=progress

Example

sudo dd if=./archlinux-2021.07.01-x86_64.iso of=/dev/sdb bs=4096 status=progress
  1. Windows

On Windows you can use Etcher to write ISOs

Download Etcher and launch it as administrator, then simply write the ISO to the desired drive.

Now BOOT the newly created Arch install media

Prepare Installation Environment

Set Mirrors

Once We’re booted into the Live media the first thing we need to do is select the proper mirrors

Run the following command to automatically rank and save mirrors

reflector --latest 20 --protocol https --sort rate --save /etc/pacman.d/mirrorlist

and refresh the Package database with

pacman -Syy

Load ZFS Modules

Now we can go ahead and load the ZFS modules for our install environment

The best way to do so would be to load a script by eoli3n on GitHub that automatically loads the needed ZFS modules.

curl https://eoli3n.github.io/archzfs/init | bash

Configure Disks

Create Partitions

Since GRUB ( Our Bootloader ) does not support booting from an encrypted boot partition we will need to create a separate boot partition with a different Filesystem like ext4 which will act as our /boot

Before we do anything we will need to initialize the disk with a new GPT partition table

Refer to the Official Arch Partioning Guide to Partition your drives

Your Partition table should look something like this

Part     Size   Type
----     ----   -------------------------
   1     100M   EFI boot partition (ef00) -> For storing EFI Files
   2     500M   Linux Filesystem ----------> For storing Linux Kernel
   3     XXXG   Solaris Root (bf00) -------> ZFS Pool

We will assume for this Tutorial that the target disk is sda so e.g. The EFI Partition would be /dev/sda1

Create ZFS Pool

Now we need to create a ZFS Pool to install Arch.

A ZFS Pool can have many configurations, it can be a single partition on a disk drive or a RAID of 1000s of disks

Since it is not possible to include every configuration you can refer how to create the Pool with your desired configuration using the Official Documentation

In this Tutorial we will be creating a ZFS Pool consisting of a single disk for simplicity

The rest of the Steps should be identical no matter what yout Encrypted Pool configuration is.

We can create a new ZFS Pool with

zpool create -f -o ashift=12         \
             -O acltype=posixacl       \
             -O relatime=on            \
             -O xattr=sa               \
             -O dnodesize=legacy       \
             -O normalization=formD    \
             -O mountpoint=none        \
             -O canmount=off           \
             -O devices=off            \
             -R /mnt                   \
             -O compression=lz4        \
             -O encryption=aes-256-gcm \
             -O keyformat=passphrase   \
             -O keylocation=prompt     \
             zroot /dev/disk/by-id/id-to-disk

Create ZFS Datasets

Once that’s done we can go ahead and create essential root datasets with

 zfs create -o mountpoint=none zroot/data
zfs create -o mountpoint=none zroot/ROOT
zfs create -o mountpoint=/ -o canmount=noauto zroot/ROOT/default
zfs create -o mountpoint=/home zroot/data/home

Now we will create some system datasets which though not required are Strongly recommended

zfs create -o mountpoint=/var -o canmount=off zroot/var
 zfs create zroot/var/log
zfs create -o mountpoint=/var/lib -o canmount=off zroot/var/lib

Optional Datasets for libvirt and Docker

 zfs create zroot/var/lib/libvirt
 zfs create zroot/var/lib/docker

Export and Import Your Pool

You can optionally (Recommended) Export and Re-import your Pool to check if the configuration is correct

Export Pool with

zpool export <Pool Name>

Example

zpool export zroot

Import Pool with

zpool import <Pool Name> -R /mnt

Example

zpool import zroot -R /mnt

Mount ZFS Datasets

Now we need to mount the ZFS datasets so we can start installing Arch

Mount the ROOT base dataset with

zfs mount <Pool Name>/ROOT/<ROOT Dataset>

Example

zfs mount zroot/ROOT/default

Now we can mount the rest of the datasets on TOP with

zfs mount -a

Mount Boot and EFI

Now we can mount our BOOT Partition with

mount <Path to Boot partition> /mnt/boot

And our EFI Partition with

mount <Path to EFI Partition> /mnt/boot/efi

Install Arch

This Tutorial will assume that your target root FS is mounted on /mnt as mentioned before

Pacstrap base

Before we can install anything we need to install the base Arch packages which include stuff like pacman to be able to do anything

Boot Strap the base image with

pacstrap /mnt base base-devel

Generate fstab

Generate a new fstab for our Install with

genfstab -f /boot -U /mnt > /mnt/etc/fstab

We won’t need to include ZFS datasets since GRUB and the ZFS Manager will mount them automatically

chroot into your target install with arch-chroot /mnt

Install The Kernel

You basically Have 3 Choices for your kernel

  1. linux

This is the vanilla Linux Kernel

  1. linux-zen

This is kernel modified slightly for better performance on Desktops and Laptops

  1. linux-lts

This is the Long term support version of Linux

Install your desired kernel with

pacman -Syy <Kernel> <Kernel>-headers

Example

pacman -Syy linux-zen linux-zen-headers

Note: You can have multiple kernels Installed

Install CPU Microcode

  • AMD
pacman -S amd-ucode
  • Intel
pacman -S intel-ucode

Install ZFS

Now we can Install the ZFS Kernel modules on our target install

Add the archzfs repo

we will use the archzfs repo to install the zfs-dkms module

Add the repo by appending the following to your /etc/pacman.conf

[archzfs]
Server = https://archzfs.com/$repo/$arch

You might also need to add their keys with

pacman-key -r DDF7DB817396A49B2A2723F7403BD972F75D9D76
pacman-key --lsign-key DDF7DB817396A49B2A2723F7403BD972F75D9D76

Refresh the Package database with pacman -Syy

Install the ZFS kernel Module

Install the kernel module with

pacman -S zfs-dkms

Note: This may take some time as we are compiling the ZFS source for all of our Kernels

Configure initramfs

Now we need to make sure that our initramfs includes the ZFS Kernel module on boot, for that we will need to edit the /etc/mkinitcpio.conf file

Specifically we need to edit the HOOKS line which looks something like this

HOOKS=(base udev autodetect modconf block filesystems keyboard fsck)

The sequence in which this elements are in this array is how they’re loaded, so we need to include the zfs module and the keyboard module early on to enter our password

It should look something like this

HOOKS=(base udev autodetect modconf block keyboard zfs filesystems)

Note the keyboard module loading BEFORE the ZFS module to allow us keyboard access to enter root password on boot

We can also omit fsck since ZFS doesn’t need it

Now Generate the new initramfs with

mkinitcpio -P

Configure systemd

Set a cache file for your ZFS Pool with

zpool set cachefile=/etc/zfs/<Pool Name>.cache <Pool Name>

enable the following services for ZFS

systemctl enable zfs-mount zfs-import-scan zfs-import-cache

Install the bootloader

We are gonna use the GRUB bootloader with UEFI for out Install

Install the grub bootloader with

pacman -S grub efibootmgr os-prober

Install GRUB to disk

Install the GRUB bootloader to disk using

ZPOOL_VDEV_NAME_PATH=1 grub-install --efi-directory=<Mountpoint of EFI Partition> --bootloader-id=<Desired Name> --target=x86_64-efi

Example

ZPOOL_VDEV_NAME_PATH=1 grub-install --efi-directory=/boot/efi --bootloader-id="ArchZFS" --target=x86_64-efi

Generate GRUB config

Now we can generate our GRUB config file with

ZPOOL_VDEV_NAME_PATH=1 grub-mkconfig -o /boot/grub/grub.cfg

Since GRUB assumes that we will be booting ther kernel from the ZFS Pool as root it generates the config file accordingly

But that’s not the case with out setup since we will be using encrypted root, So we will nned to edit the grub config file and replace the boot disk parametre

This is only needed to be done ONCE, or when adding a new kernel e.g You are using the linux kernel the decided to add linux-lts as well later on.

Use the following command to replace /ROOT with <Pool Name>/ROOT

sed -i "s@/ROOT@<Pool Name>/ROOT@" /boot/grub/grub.cfg

Example

sed -i "s@/ROOT@zroot/ROOT@" /boot/grub/grub.cfg

Set Timezone and Locale

Timezone

set the timezone for your install with

ln -s /usr/share/zoneinfo/<Your Timezone> /etc/localtime

Example

ln -s /usr/share/zoneinfo/Asia/Kolkata /etc/localtime

Generate /etc/adjtime with

hwclock --systohc

Locale

Uncomment Your desired locale from /etc/locale.gen eg. en_US.UTF-8

Then simply run

locale-gen

Now create anew file /etc/loale.conf and add your generated locale to it

Example

echo "LANG=en_US.UTF-8" >> /etc/locale.conf

Install the following recommended packages

NTP

pacman -S ntp
systemctl enable ntpd

Text Editor

Install your choice of text editor e.g nano

pacman -S nano

Networking

Install NetworkManager and dhcpcd for wired networking and iwd if you plan on using wireless from CLI

pacman -S networkmanager dhcpcd iwd
systemctl enable dhcpcd NetworkManager

Configure Users

Set a root Password with passwd

Create Your user with

useradd -m <user>

and set Password with

passwd <user>

You can skip the -m if you created a dataset for the user like we mentioned before

Don’t forget to change permissions for the user home directory with

chown <user>:<user> /home/<user>

Install a Desktop Environment

This Step is OPTIONAL

Now you can install a desktop environment like kde

Refer to the Official Arch Documentation for a full guide

To install a basic kde desktop environment simply run

pacman -S plasma pipewire pipewire-pulse sddm pipewire-media-session konsole

If you wanna use wayland, Install the plasma-wayland-session package

pacman -Sy  plasman-wayland-session

Now we can exit from our install and test it

Unmount and reboot

Exit the install environment with exit

Unmount all your disks

umount /mnt/boot/efi
umount /mnt/boot

And finally export the ZFS Pool with

zpool export <Pool Name>

Example

zpool export zroot

Now Simply reboot into your new new install

You should now be prompted for your Pool Password every time you boot.

You can optionally use shavee to encrypt home directories with a diffrent key.

Let me know if i missed anything.