My Arch Install
1. Pre-Flight
Boot the Arch live USB in UEFI mode. Confirm it:
ls /sys/firmware/efi/efivars
Set the keymap immediately. You will be typing a LUKS passphrase shortly, and the default US layout will silently mangle it.
loadkeys uk
Connect to the network and synchronise the clock:
ping -c 3 archlinux.org
# wireless if needed
iwctl
# station wlan0 scan
# station wlan0 connect <ssid>
timedatectl set-ntp true
timedatectl status
2. Storage Architecture
The partition layout is straightforward:
| Partition | Size | Role |
|---|---|---|
/dev/nvme0n1p1 | 1 GiB | EFI System Partition — vfat, unencrypted |
/dev/nvme0n1p2 | 2 GiB | /boot — ext4, unencrypted |
/dev/nvme0n1p3 | ~253 GiB | LUKS2 container |
Inside the LUKS container, LVM carves out four volumes:
| Volume | Size | Filesystem |
|---|---|---|
vg0/swap | 16 GiB | swap |
vg0/root | 50 GiB | XFS |
vg0/var | 20 GiB | XFS |
vg0/home | ~167 GiB | XFS |
16 GiB of swap is twice the physical RAM. That covers hibernation without spilling.
2.1 Wipe the Drive
wipefs -a /dev/nvme0n1
2.2 Partition
parted -s /dev/nvme0n1 mklabel gpt
parted -s /dev/nvme0n1 mkpart ESP fat32 1MiB 1025MiB
parted -s /dev/nvme0n1 set 1 esp on
parted -s /dev/nvme0n1 mkpart primary ext4 1025MiB 3073MiB
parted -s /dev/nvme0n1 mkpart primary 3073MiB 100%
2.3 Encrypt the Root Partition
cryptsetup luksFormat --type luks2 --cipher aes-xts-plain64 --key-size 512 /dev/nvme0n1p3
cryptsetup open /dev/nvme0n1p3 cryptroot
/boot sits on its own unencrypted partition — GRUB reads it directly. GRUB_ENABLE_CRYPTODISK is not needed here.
2.4 LVM
pvcreate /dev/mapper/cryptroot
vgcreate vg0 /dev/mapper/cryptroot
lvcreate -L 16G -n swap vg0
lvcreate -L 50G -n root vg0
lvcreate -L 20G -n var vg0
lvcreate -l 100%FREE -n home vg0
2.5 Format
mkfs.vfat -F32 /dev/nvme0n1p1
mkfs.ext4 /dev/nvme0n1p2
mkfs.xfs /dev/vg0/root
mkfs.xfs /dev/vg0/var
mkfs.xfs /dev/vg0/home
mkswap /dev/vg0/swap
2.6 Mount
mount /dev/vg0/root /mnt
mkdir -p /mnt/{boot/efi,home,var}
mount /dev/nvme0n1p2 /mnt/boot
mount /dev/nvme0n1p1 /mnt/boot/efi
mount /dev/vg0/var /mnt/var
mount /dev/vg0/home /mnt/home
swapon /dev/vg0/swap
3. Base Installation
pacstrap -K /mnt \
base base-devel linux linux-headers linux-firmware \
intel-ucode \
lvm2 cryptsetup xfsprogs e2fsprogs dosfstools \
neovim tmux git networkmanager man-db man-pages sudo \
mesa vulkan-intel intel-media-driver \
hyprland waybar rofi-wayland \
xdg-desktop-portal-hyprland xdg-desktop-portal-gtk \
xdg-user-dirs polkit-gnome \
ly \
kitty wl-clipboard grim slurp \
hypridle hyprlock mako \
pipewire pipewire-alsa pipewire-pulse pipewire-jack wireplumber pavucontrol \
bluez bluez-utils \
tlp tlp-rdw acpid brightnessctl \
ttf-ibm-plex noto-fonts noto-fonts-emoji ttf-jetbrains-mono-nerd
Then generate the filesystem table:
genfstab -U /mnt >> /mnt/etc/fstab
cat /mnt/etc/fstab
4. System Configuration
arch-chroot /mnt
4.1 Timezone and Locale
ln -sf /usr/share/zoneinfo/Africa/Lagos /etc/localtime
hwclock --systohc
sed -i 's/^#en_GB.UTF-8 UTF-8/en_GB.UTF-8 UTF-8/' /etc/locale.gen
locale-gen
echo "LANG=en_GB.UTF-8" > /etc/locale.conf
4.2 Keymap
localectl requires a running systemd instance. Inside arch-chroot it will either fail silently or error out, leaving you with no keymap on first boot. Write directly to vconsole.conf instead — the keyboard and keymap mkinitcpio hooks read it automatically.
echo "KEYMAP=uk" > /etc/vconsole.conf
4.3 Network Identity
echo "arch" > /etc/hostname
cat <<EOF > /etc/hosts
127.0.0.1 localhost
::1 localhost
127.0.1.1 arch.localdomain arch
EOF
systemctl enable NetworkManager
4.4 Initramfs
Edit /etc/mkinitcpio.conf and set the HOOKS array. The ordering is not optional — encrypt must come before lvm2, and resume must follow lvm2.
HOOKS=(base udev autodetect microcode modconf kms keyboard keymap consolefont block encrypt lvm2 resume filesystems fsck)
nvim /etc/mkinitcpio.conf
mkinitcpio -P
5. Bootloader
pacman -S grub efibootmgr
Get the UUID of the LUKS partition:
blkid /dev/nvme0n1p3
Edit /etc/default/grub. Set GRUB_CMDLINE_LINUX:
GRUB_CMDLINE_LINUX="cryptdevice=UUID=<uuid>:cryptroot root=/dev/mapper/vg0-root resume=/dev/mapper/vg0-swap"
Replace <uuid> with the actual string from blkid. The resume= parameter enables hibernation via the swap LV. Drop it if you do not need hibernation.
nvim /etc/default/grub
Install and generate the config. The --removable flag writes a fallback EFI entry that survives firmware resets.
grub-install --target=x86_64-efi --efi-directory=/boot/efi \
--bootloader-id=GRUB --removable
grub-mkconfig -o /boot/grub/grub.cfg
6. User Management
passwd
useradd -m -s /bin/bash -G wheel,video,audio,storage,input osaigbovo
passwd osaigbovo
# uncomment: %wheel ALL=(ALL:ALL) ALL
EDITOR=nvim visudo
The input group is required for Wayland input device access under Hyprland.
7. Desktop Services
Enable everything before the first reboot:
systemctl enable ly
systemctl enable bluetooth
systemctl enable tlp
systemctl enable tlp-rdw
systemctl enable acpid
# tlp manages rfkill — mask the systemd units to avoid conflicts
systemctl mask systemd-rfkill.service systemd-rfkill.socket
Pipewire runs as a user session service, not a system service. On first login, enable it as your user:
systemctl --user enable --now pipewire pipewire-pulse wireplumber
systemctl --user enable --now xdg-desktop-portal-hyprland
7.1 Hyprland Configuration
Add these to ~/.config/hypr/hyprland.conf to start the essential session components:
exec-once = /usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1
exec-once = mako
exec-once = waybar
exec-once = hypridle
The UHD 620 needs a few environment variables set for correct VA-API, cursor rendering, and Qt/Firefox Wayland compatibility:
env = LIBVA_DRIVER_NAME,iHD
env = WLR_NO_HARDWARE_CURSORS,1
env = XDG_SESSION_TYPE,wayland
env = XDG_SESSION_DESKTOP,Hyprland
env = QT_QPA_PLATFORM,wayland
env = MOZ_ENABLE_WAYLAND,1
8. Finalisation
exit
swapoff -a
umount -R /mnt
vgchange -an vg0
cryptsetup close cryptroot
reboot
On reboot: GRUB hands off to the kernel, the initramfs prompts for the LUKS passphrase, LVM activates, root mounts, ly presents the login, and Hyprland takes over.