Arch Linux Installation Guide with Full LUKS Encryption

June 13, 2026Last Modified: July 22, 2026

In this guide, I walk you through the process of installing Arch Linux without `archinstall` and configuring `mkinitcpio` and the kernel parameters to unlock a fully encrypted root partition using either an external USB drive keyfile or a fallback passphrase.

This casual guide serves as an archive for my future self, who will inevitably install Arch Linux again and might need some guidance from the past on how to get a fully encrypted LUKS root partition working with an external USB keyfile.

First, you will need a live USB containing the Arch Linux ISO. I decided to partition a 64 GB USB drive into two partitions. The first partition contains the installation ISO, which can be written using:

dd if=arch-linux.iso of=/dev/sda1 bs=4M status=progress conv=fsync oflag=direct

The second partition can be formatted as either EXT4 or FAT32:

mkfs.ext4 /dev/sda2

Next, mount it and create the keyfile:

mount /dev/sda2 /mnt/key --mkdir
dd if=/dev/urandom of=/mnt/key/root.key bs=512 count=8
chmod 000 /mnt/key/root.key
chown root:root /mnt/key/root.key

Now you can follow the Arch Linux Installation Guide (obviously). Here are some important considerations.

Securely wipe the SSD. In my case, it is an NVMe drive, so I can use nvme-cli, which is included in the Arch Linux ISO:

nvme format /dev/nvme0n1 --ses=<1,2>

Depending on the device, it may support either User Data Erase (1) or Cryptographic Erase (2).

Create the following partitions:

Mount  Device          Size  Format
/boot  /dev/nvme0n1p1  1G    mkfs.fat -F 32
/      /dev/nvme0n1p2  461G
[SWAP] /dev/nvme0n1p3  15G   mkswap

For the root (/) partition, initialize the LUKS container and create the filesystem:

cryptsetup -v luksFormat /dev/nvme0n1p2
cryptsetup open /dev/nvme0n1p2 root
mkfs.ext4 /dev/mapper/root

Assuming the USB partition is mounted under /mnt/key and you have already entered the installation with arch-chroot, add the keyfile (and optionally another backup passphrase):

cryptsetup luksAddKey /dev/nvme0n1p2 /mnt/key/root.key

Proceed with the rest of the installation. For the bootloader, I use GRUB with UEFI:

pacman -S grub efibootmgr
grub-install --target=x86_64-efi --efi-directory=/boot --bootloader-id=ARCH

Before generating the GRUB configuration, add the following kernel parameters to /etc/default/grub:

GRUB_CMDLINE_LINUX="rd.luks.name=<root-UUID(encrypted)>=root root=/dev/mapper/root rd.retry=10"

Then generate the configuration:

grub-mkconfig -o /boot/grub/grub.cfg

We also need to configure mkinitcpio by editing /etc/mkinitcpio.conf:

MODULES=(... vfat ext4 usb_storage uas xhci_pci ehci_pci)
...
HOOKS=(base systemd autodetect microcode modconf kms keyboard sd-vconsole block sd-encrypt filesystems fsck)

Next, configure /etc/crypttab.initramfs:

root UUID=<root-UUID(encrypted)> root.key:UUID=<usb-UUID> keyfile-timeout=10s

Finally, regenerate the initramfs:

mkinitcpio -P

At boot, the system will attempt to load root.key from the USB drive. If it is not found, it will fall back to prompting for the LUKS passphrase.

Other Configurations

Create a user:

useradd -mG wheel <user>

Remember to enable the wheel group in /etc/sudoers.

Useful packages:

Microcode:         intel-ucode
Power management:  tlp (configure `/etc/tlp.conf` and run `tlp start`)
Audio:             alsa-utils pipewire pipewire-alsa pipewire-pulse wireplumber
Audio firmware:    sof-firmware alsa-firmware alsa-ucm-conf (reboot, then test with `alsamixer` and `speaker-test`)
Fonts:             terminus-font (configure `/etc/vconsole.conf`)
Bluetooth:         bluez bluez-utils
Hyprland:          hyprland kitty hyprlauncher firefox
Yazi:              ffmpeg 7zip jq poppler fd ripgrep fzf zoxide imagemagick yazi
NVIDIA:            nvidia-dkms nvidia-utils egl-wayland

Enable the required services:

systemctl enable --now NetworkManager
systemctl enable --now tlp
systemctl enable --now alsa-state.service
systemctl enable --now alsa-restore.service
systemctl --user enable --now pipewire.service
systemctl --user enable --now pipewire-pulse.service
systemctl --user enable --now wireplumber.service
systemctl enable --now bluetooth.service

If using NVIDIA with Hyprland, include the following modules in mkinitcpio.conf:

MODULES=(i915 nvidia nvidia_modeset nvidia_uvm nvidia_drm ...)

Then regenerate the initramfs:

mkinitcpio -P