Prepare Installation Media
- Download the latest Arch ISO
- Write image to a USB media
- 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
- 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
- linux
This is the vanilla Linux Kernel
- linux-zen
This is kernel modified slightly for better performance on Desktops and Laptops
- 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 Recommended packages
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.