arch install guide
last modified: 2026-03-26
preamble
most, if not all of this information is sourced from the arch wiki and man pages. this page is purely meant to be a concise installation guide for my preferred configuration.
features
- LUKS encryption on a partition with an LVM container inside (LVM on LUKS)
- LVM with separate logical volumes for
/,/homeand[SWAP] - systemd-boot instead of GRUB
- secure boot using
sbctlwith self-signed keys
pre-install
- boot into the UEFI firmware settings
- clear the secure boot keys and enter secure boot setup mode
- reboot into the live install media
wireless connection setup (skip if using ethernet)
using iwd:
# iwctl
[iwd]# device list
[iwd]# device <wlan device name> set-property Powered on
[iwd]# adapter <adapter name> set-property Powered on
[iwd]# station <wlan device name> scan
[iwd]# station <wlan device name> get-networks
[iwd]# station <wlan device name> connect <ssid>
update system clock
run timedatectl to check if timezone is correct, if not, run timedatectl set-timezone <region>/<city>; full list of zones available can be found in /usr/share/zoneinfo/.
partitioning
- identify block device of target physical disk with
lsblkorfdisk -l, in this example, it is/dev/nvme0n1. - partition said block device into two, the first should be 512MB-1GB in size for the boot partition, and the second will be used for the LUKS encrypted container and consume the rest of the free storage.
- in this example,
/dev/nvme0n1is the physical disk,/dev/nvme0n1p1is the boot partition, and/dev/nvme0n1p2is the LUKS partition
encryption
encrypt and open the designated LUKS partition:
# cryptsetup luksFormat /dev/nvme0n1p2
# cryptsetup open /dev/nvme0n1p2 encrypted
the LUKS partition is now open and mapped as /dev/mapper/encrypted.
create the physical volume inside of the opened LUKS partition:
# pvcreate /dev/mapper/encrypted
create the volume group that will house the /, /home, and [SWAP] logical volumes, we will call this volume group "main":
# vgcreate main /dev/mapper/encrypted
create said logical volumes, swap here is 4GB on a machine with 16GB of ram, but adjust swap volume size accordingly if necessary:
# lvcreate -L 4G -n swap main
# lvcreate -L 32G -n root main
# lvcreate -l 100%FREE -n home main
format the logical volumes, here we are using ext4 for root and home:
# mkfs.ext4 /dev/main/root
# mkfs.ext4 /dev/main/home
# mkswap /dev/main/swap
format boot partition
UEFI uses FAT32:
# mkfs.fat -F32 /dev/nvme0n1p1
mounting
mount the logical volumes and boot partition, initialize swap:
# mount /dev/main/root /mnt
# mount --mkdir /dev/main/home /mnt/home
# mount --mkdir /dev/nvme0n1p1 /mnt/boot
# swapon /dev/main/swap
# lsblk /dev/nvme0n1p1
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
nvme0n1 259:0 0 465.8G 0 disk
├─nvme0n1p1 259:1 0 1G 0 part /mnt/boot
└─nvme0n1p2 259:2 0 464.8G 0 part
└─encrypted 253:0 0 464.7G 0 crypt
├─main-swap 253:1 0 4G 0 [SWAP]
├─main-root 253:2 0 32G 0 /mnt
└─main-home 253:3 0 428.7G 0 /mnt/home
pacstrap
# pacstrap -K /mnt base base-devel linux-hardened linux-firmware cryptsetup 2 sbctl efibootmgr nvim sudo man-db amd-ucode sof-firmware tmux iwd systemd-resolvconf wireguard-tools fwupd btop pacman-contrib
generate fstab
# genfstab -U /mnt >> /mnt/etc/fstab
chroot
# arch-chroot /mnt
in chroot, before running locale-gen, ensure that you have uncommented your desired locale in /etc/locale.gen:
# ln -sf /usr/share/zoneinfo/<region>/<city> /etc/localtime
# hwclock --systohc
# nvim /etc/locale.gen
# locale-gen
create /etc/locale.conf, assuming desired locale is en_US, do:
LANG=en_US.UTF-8
set the hostname, create a user and add them to the wheel group, set a password for them and the root user:
# nvim /etc/hostname
# passwd
# useradd -m <username>
# usermod -aG wheel <username>
# passwd <username>
uncomment the sudoers file line that allows the wheel group to execute as superuser:
# export EDITOR=/usr/bin/nvim
# visudo
enable keyd and necessary services for wireless connections and DNS resolution:
# systemctl enable keyd
# systemctl enable iwd
# systemctl enable systemd-resolved
enable iwd's built-in DHCP client:
# mkdir /etc/iwd
# nvim /etc/iwd/main.conf
-------------------------
[General]
EnableNetworkConfiguration=true
create keyd config to remap capslock to escape:
# mkdir /etc/keyd
# nvim /etc/keyd/default.conf
-----------------------------
[ids]
*
[main]
capslock = esc
edit mkinitcpio hooks to support LUKS encryption and LVM:
# nvim /etc/mkinitcpio.conf
---------------------------
HOOKS=(base systemd autodetect microcode modconf kms keyboard keymap block sd-encrypt lvm2 filesystems fsck)
regenerate initramfs:
# mkinitcpio -P
install bootloader:
# bootctl install
create bootloader entry:
nvim /boot/loader/entries/arch.conf
-------------------------------------
title arch
linux /vmlinuz-linux-hardened
initrd /initramfs-linux-hardened.img
options rd.luks.name=</dev/nvme0n1p2 uuid>=encrypted root=/dev/main/root
set up secure boot:
# sbctl status
# sbctl create-keys
# sbctl enroll-keys
before running sbctl enroll-keys, check if your device firmware is known to have issues with self-signed keys, if unsupported, this can brick UEFI firmwares, if in doubt run sbctl enroll-keys -m instead to sign the keys with microsoft's certificates.
sign the bootloader and kernel:
# sbctl sign -s /boot/vmlinuz-linux-hardened
# sbctl sign -s /boot/EFI/BOOT/BOOTX64.EFI
verify secure boot:
# sbctl verify
# sbctl status
secure boot should now be active, we can then setup auto-signing that triggers when the bootloader update:
# sbctl sign -s -o /usr/lib/systemd/boot/efi/systemd-bootx64.efi.signed /usr/lib/systemd/boot/efi/systemd-bootx64.efi
and enable the systemd service to auto-update the bootloader if a new version is available every boot:
# systemctl enable systemd-boot-update.service
exit chroot and reboot into the new system:
# exit
# umount -R /mnt
# swapoff /dev/main/swap
# reboot
post-install
enable systemd-resolved's stub:
# ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf