Archinstall

  1. Pre-Flight Boot the Arch Linux live USB in UEFI mode and confirm the firmware interface:
# CHECK UEFI FIRMWARE VARIABLES
ls /sys/firmware/efi/efivars

Set the keyboard layout immediately. The default US layout will mangle your LUKS passphrase during creation if you rely on a UK keyboard.

# LOAD UK KEYBOARD LAYOUT
loadkeys uk

Connect to the network and synchronise the system clock:

# TEST NETWORK CONNECTIVITY
ping -c 3 archlinux.org

# CONNECT WIRELESSLY VIA IWCTL IF REQUIRED
iwctl
# station wlan0 scan
# station wlan0 connect <ssid>

# SYNCHRONISE SYSTEM CLOCK
timedatectl set-ntp true
timedatectl status
  1. Storage Architecture The system resides on a single NVMe drive. The partition table divides the drive into an EFI system partition, an unencrypted boot partition, and a primary encrypted container:
PartitionSizeRoleFilesystem
/dev/nvme0n1p11 GiBEFI System Partitionvfat, unencrypted
/dev/nvme0n1p22 GiB/bootext4, unencrypted
/dev/nvme0n1p3~253 GiBLUKS2 containerencrypted XTS-plain64

Inside the LUKS container, Logical Volume Management carves out four volumes:

VolumeSizeFilesystemRole
vg0/swap16 GiBswapvirtual memory and hibernation
vg0/root50 GiBXFSsystem root
vg0/var20 GiBXFSvariable data and logs
vg0/home~167 GiBXFSuser directories

2.1 Wipe the Drive

# WIPE EXISTING SIGNATURES AND PARTITIONS
wipefs -a /dev/nvme0n1

2.2 Partition

# CREATE GPT PARTITION TABLE AND SLICES
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

# INITIALISE LUKS2 CONTAINER WITH 512 BIT KEY
cryptsetup luksFormat --type luks2 --cipher aes-xts-plain64 --key-size 512 /dev/nvme0n1p3

# OPEN ENCRYPTED CONTAINER
cryptsetup open /dev/nvme0n1p3 cryptroot

2.4 LVM

# INITIALISE PHYSICAL VOLUME AND VOLUME GROUP
pvcreate /dev/mapper/cryptroot
vgcreate vg0 /dev/mapper/cryptroot

# ALLOCATE LOGICAL VOLUMES
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

# FORMAT BOOT AND EFI PARTITIONS
mkfs.vfat -F32 /dev/nvme0n1p1
mkfs.ext4      /dev/nvme0n1p2

# FORMAT LOGICAL VOLUMES
mkfs.xfs /dev/vg0/root
mkfs.xfs /dev/vg0/var
mkfs.xfs /dev/vg0/home
mkswap   /dev/vg0/swap

2.6 Mount Mount the filesystems in strict hierarchical order to prevent directory obscuration:

# MOUNT ROOT AND CREATE BASE DIRECTORY STRUCTURE
mount /dev/vg0/root /mnt
mkdir -p /mnt/{boot,home,var}

# MOUNT BOOT AND CREATE EFI MOUNT POINT INSIDE IT
mount /dev/nvme0n1p2 /mnt/boot
mkdir -p /mnt/boot/efi
mount /dev/nvme0n1p1 /mnt/boot/efi

# MOUNT REMAINING LOGICAL VOLUMES AND ACTIVATE SWAP
mount /dev/vg0/var   /mnt/var
mount /dev/vg0/home  /mnt/home
swapon /dev/vg0/swap
  1. Base Installation Install the base operating system, hardware drivers, Niri, and your Wayland utility stack:
# INSTALL BASE SYSTEM AND PACKAGES
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 \
  niri waybar rofi-wayland \
  xdg-desktop-portal-gnome xdg-desktop-portal-gtk \
  xdg-user-dirs polkit-gnome \
  ly \
  kitty wl-clipboard grim slurp \
  swaybg swaylock swayidle 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

Generate the filesystem table using universally unique identifiers:

# GENERATE FILESYSTEM TABLE
genfstab -U /mnt >> /mnt/etc/fstab
cat /mnt/etc/fstab
  1. System Configuration Enter the new system installation:
# ENTER CHROOT ENVIRONMENT
arch-chroot /mnt

4.1 Timezone and Locale

# CONFIGURE TIMEZONE AND CLOCK
ln -sf /usr/share/zoneinfo/Africa/Lagos /etc/localtime
hwclock --systohc

# GENERATE AND APPLY LOCALE
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 Write the configuration directly to /etc/vconsole.conf. The initramfs generation hooks read this file automatically:

# PERSIST CONSOLE KEYBOARD LAYOUT
echo "KEYMAP=uk" > /etc/vconsole.conf

4.3 Network Identity

# SET HOSTNAME AND HOSTS ENTRIES
echo "arch" > /etc/hostname

cat <<EOF> /etc/hosts
127.0.0.1   localhost
::1         localhost
127.0.1.1   arch.localdomain arch
EOF

# ENABLE NETWORK MANAGEMENT
systemctl enable NetworkManager

4.4 Initramfs Edit /etc/mkinitcpio.conf and configure the HOOKS array. Placing microcode immediately after autodetect bundles CPU microcode updates directly into the main kernel initramfs image:

# MODIFY INITRAMFS HOOKS
nvim /etc/mkinitcpio.conf

Ensure the line reads exactly:

HOOKS=(base udev autodetect microcode modconf kms keyboard keymap consolefont block encrypt lvm2 resume filesystems fsck)

Generate the boot images:

# COMPILE INITRAMFS IMAGES
mkinitcpio -P
  1. Bootloader
# INSTALL GRUB AND EFI BOOT MANAGEMENT TOOLS
pacman -S grub efibootmgr

Retrieve the UUID of your encrypted LUKS partition:

# LOCATE LUKS PARTITION UUID
blkid /dev/nvme0n1p3

Edit /etc/default/grub and populate the GRUB_CMDLINE_LINUX variable with the LUKS UUID and LVM volume mappings:

# CONFIGURE GRUB KERNEL PARAMETERS
nvim /etc/default/grub

Set the line as follows, substituting <uuid> with the actual string from blkid:

GRUB_CMDLINE_LINUX="cryptdevice=UUID=<uuid>:cryptroot root=/dev/mapper/vg0-root resume=/dev/mapper/vg0-swap"

Install the bootloader to the EFI directory and generate the configuration file:

# INSTALL GRUB TO EFI PARTITION
grub-install --target=x86_64-efi --efi-directory=/boot/efi \
  --bootloader-id=GRUB --removable

# GENERATE GRUB CONFIGURATION
grub-mkconfig -o /boot/grub/grub.cfg
  1. User Management
# ASSIGN ROOT PASSWORD
passwd

# CREATE PRIMARY USER ACCOUNT WITH HARDWARE GROUPS
useradd -m -s /bin/bash -G wheel,video,audio,storage,input osaigbovo
passwd osaigbovo

# GRANT SUDO PRIVILEGES TO WHEEL GROUP
EDITOR=nvim visudo

Uncomment the %wheel ALL=(ALL:ALL) ALL line inside the sudoers file.

  1. System Services Enable required system daemons before exiting the chroot environment:
# ENABLE DISPLAY MANAGER AND HARDWARE SERVICES
systemctl enable ly
systemctl enable bluetooth
systemctl enable tlp
systemctl enable tlp-rdw
systemctl enable acpid

# MASK RFKILL UNITS TO PREVENT TLP CONFLICTS
systemctl mask systemd-rfkill.service systemd-rfkill.socket

PipeWire and WirePlumber operate exclusively as user session daemons. Modern Arch Linux packages configure socket activation by default. When you log in as osaigbovo for the first time, systemd automatically initiates the audio server and desktop portal infrastructure without requiring manual intervention.

7.1 Niri Configuration Create the Niri configuration directory and file under your standard user account after first boot:

# CREATE NIRI CONFIGURATION DIRECTORY
mkdir -p ~/.config/niri
nvim ~/.config/niri/config.kdl

Populate config.kdl with your environment variables, background, locker, idle management, and status bar configurations:

// CONFIGURE WAYLAND ENVIRONMENT VARIABLES FOR INTEL GRAPHICS
environment {
    LIBVA_DRIVER_NAME "iHD"
    XDG_SESSION_TYPE "wayland"
    XDG_SESSION_DESKTOP "niri"
    XDG_CURRENT_DESKTOP "niri"
    QT_QPA_PLATFORM "wayland"
    MOZ_ENABLE_WAYLAND "1"
}

// SPAWN SESSION DAEMONS AND UTILITIES AT STARTUP
spawn-at-startup "/usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1"
spawn-at-startup "mako"
spawn-at-startup "waybar"
spawn-at-startup "swaybg" "-m" "fill" "-i" "/home/osaigbovo/.config/wallpaper.png"
spawn-at-startup "swayidle" "-w" "timeout" "300" "swaylock -f" "timeout" "600" "niri msg action power-off-monitors" "resume" "niri msg action power-on-monitors"
  1. Finalisation Exit the chroot environment, unmount all disks, deactivate the logical volumes, seal the LUKS container, and reboot the machine:
# EXIT CHROOT
exit

# DEACTIVATE SWAP AND UNMOUNT FILESYSTEMS
swapoff -a
umount -R /mnt

# DEACTIVATE VOLUME GROUP AND CLOSE LUKS CONTAINER
vgchange -an vg0
cryptsetup close cryptroot

# REBOOT SYSTEM
reboot