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:

PartitionSizeRole
/dev/nvme0n1p11 GiBEFI System Partition — vfat, unencrypted
/dev/nvme0n1p22 GiB/boot — ext4, unencrypted
/dev/nvme0n1p3~253 GiBLUKS2 container

Inside the LUKS container, LVM carves out four volumes:

VolumeSizeFilesystem
vg0/swap16 GiBswap
vg0/root50 GiBXFS
vg0/var20 GiBXFS
vg0/home~167 GiBXFS

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.