Skip to content

Installing Arch Linux

|

In this guide we’ll walk through how I like to set up Arch Linux. The configured system will have the fallowing features:

  • Btrfs filesystem
  • Secure boot
  • UKI EFI boot
  • Encrypted root partition unlocked with TPM module
  • Separate UKI entries for snapshots taken before updates

Getting Ready

Update the System Clock

First start by updating the system clock:

Terminal window
timedatectl set-timezone Europe/Berlin

Disk Setup

Identify your disk:

Terminal window
lsblk

Create partitions:

Terminal window
echo -e "label: gpt\n,512M,U\n,8G,S\n,,L" | sfdisk /dev/nvme0n1

This creates:

  • 512M EFI boot partition
  • 8G swap partition
  • Remaining space for Linux filesystem

Format partitions:

Terminal window
mkfs.fat -F32 -n 'ARCH BOOT' /dev/nvme0n1p1
mkswap -L 'Arch Swap' /dev/nvme0n1p2
mkfs.btrfs -L 'Arch OS' /dev/nvme0n1p3

Setting up Btrfs

It is recommended to create subvolumes for the root partition. An example layout is:

  • Directory@ mounted at /
    • @home mounted at /home
    • @log mounted at /var/log
    • @pkg mounted at /var/cache/pacman/pkg
    • @snapshots mounted at /.snapshots
    • @nocow mounted at /nocow
Terminal window
mount /dev/nvme0n1p3 /mnt
btrfs subvolume create /mnt/@
btrfs subvolume create /mnt/@home
btrfs subvolume create /mnt/@log
btrfs subvolume create /mnt/@pkg
btrfs subvolume create /mnt/@snapshots
btrfs subvolume create /mnt/@nocow
umount /mnt

Mount the Filesystems

Terminal window
mount -o subvol=@,ssd,compress=zstd:2 /dev/nvme0n1p3 /mnt
mkdir -p /mnt/{boot,efi/EFI/Linux,home,var/{log,cache/pacman},.snapshots,nocow}
mount -o subvol=@home,compress=zstd:2 /dev/nvme0n1p3 /mnt/home
mount -o subvol=@log,compress=zstd:2 /dev/nvme0n1p3 /mnt/var/log
mount -o subvol=@pkg,compress=zstd:2 /dev/nvme0n1p3 /mnt/var/cache/pacman
mount -o subvol=@snapshots,compress=zstd:2 /dev/nvme0n1p3 /mnt/.snapshots
mount -o subvol=@nocow,nodatacow /dev/nvme0n1p3 /mnt/nocow
mount /dev/nvme0n1p1 /mnt/efi
swapon /dev/nvme0n1p2

This should result in the following mount points:

  • Directory/mnt
    • Directoryefi/
      • DirectoryEFI/
        • DirectoryLinux/
    • Directoryhome/
    • Directoryvar/
      • Directorylog/
      • Directorycache/
        • Directorypacman/
    • Directory.snapshots/
    • Directorynocow/

Installing Linux

Start with updating the mirrors:

Terminal window
reflector --latest 5 --protocol http --protocol https --sort rate --save /etc/pacman.d/mirrorlist

Install Base System

Install the essential base packages:

Terminal window
pacstrap -K /mnt base linux linux-firmware sudo git base-devel rust

These packages provide:

  • base: Minimal base system
  • linux: Linux kernel
  • linux-firmware: Hardware firmware
  • sudo: Allows privilege escalation for administrative tasks
  • git, base-devel, rust: Required for building AUR packages later

Configuring the System

First start by generating the fstab:

Terminal window
genfstab -U /mnt >> /mnt/etc/fstab

Configure basic system settings with systemd-firstboot:

Terminal window
systemd-firstboot --root /mnt \
--hostname=emirhans-laptop \
--locale=en_US.UTF-8 \
--keymap=us \
--timezone=Europe/Berlin

Now you can chroot into the new system:

Terminal window
arch-chroot /mnt

Configure Pacman

First, configure pacman settings and enable multilib repository:

Terminal window
sed -i 's/#Color/Color/' /etc/pacman.conf
sed -i 's/#VerbosePkgLists/VerbosePkgLists/' /etc/pacman.conf
sed -i 's/ParallelDownloads = 5/ParallelDownloads = 10/' /etc/pacman.conf
sed -i '/^\[options\]/a ILoveCandy' /etc/pacman.conf
# Enable multilib repository
sed -i '/^#\[multilib\]/,/^#Include.*mirrorlist/ s/^#//' /etc/pacman.conf
# Update package database
pacman -Sy

Setting up the System

Generate additional locales and set up users:

Terminal window
# Generate additional locales
echo 'de_DE.UTF-8 UTF-8' >> /etc/locale.gen
echo 'en_DK.UTF-8 UTF-8' >> /etc/locale.gen
echo 'en_GB.UTF-8 UTF-8' >> /etc/locale.gen
echo 'en_IE.UTF-8 UTF-8' >> /etc/locale.gen
echo 'en_US.UTF-8 UTF-8' >> /etc/locale.gen
echo 'tr_TR.UTF-8 UTF-8' >> /etc/locale.gen
locale-gen

Setting up Users

Start by setting the root password:

Terminal window
passwd

This will prompt you to enter a new password for the root user. After entering the password twice you can continue by creating a non-root user:

Terminal window
# First create groups some system groups
groupadd -r storage
groupadd -r power
groupadd -r plugdev
useradd -m -G wheel,storage,power,plugdev -s /bin/bash emirhan
# Set the password for the user
passwd emirhan

Enable sudo for the wheel group:

Terminal window
sed -i 's/^# %wheel ALL=(ALL:ALL) ALL/%wheel ALL=(ALL:ALL) ALL/' /etc/sudoers

Now we can switch to the new user for the rest of the installation:

Terminal window
su emirhan

Optimize Build Configuration

Configure makepkg to use all available CPU cores for faster compilation:

Terminal window
sudo sed -i 's/#MAKEFLAGS="-j2"/MAKEFLAGS="-j$(nproc)"/' /etc/makepkg.conf

This replaces the default #MAKEFLAGS="-j2" with MAKEFLAGS="-j$(nproc)" to utilize all available CPU cores.

Install AUR Helper

Install paru to manage AUR packages:

Terminal window
cd $(mktemp -d)
git clone https://aur.archlinux.org/paru.git
cd paru
makepkg -si

Install Additional Packages

Now that we have the AUR helper set up, install additional packages and AUR packages using the package selector:

📦 Customize Package Selection

Generated paru command
paru -S --needed

Configure Installed Packages

Configure reflector and enable services:

Terminal window
# Configure reflector
sudo tee /etc/xdg/reflector/reflector.conf > /dev/null <<EOF
--save /etc/pacman.d/mirrorlist
--protocol https
--latest 5
--sort rate
EOF
# Enable reflector timer
sudo systemctl enable reflector.timer
# Enable services (after packages are installed)
sudo systemctl enable NetworkManager
sudo systemctl enable bluetooth.service
# Enable display manager (choose one based on what you installed)
sudo systemctl enable sddm.service # For SDDM (KDE-based)
# sudo systemctl enable gdm.service # For GDM (GNOME-based)
# Change shell to zsh (if zsh was installed)
chsh -s /bin/zsh

Configuring the Bootloader

There are multiple bootloaders you can use. The most common ones are GRUB and systemd-boot. You can find documentation on how to configure these bootloaders also in my wiki under the Arch Linux section. We are going to configure BIOS to boot directly into linux kernel. But it is recommended to configure some bootloader as a fallback option or in case your motherboard does not support booting directly into the kernel.

Setting up Firewall

If you were fallowing the guide you should have installed firewalld too. You can enable and configure it, here is an example configuration:

Terminal window
sudo systemctl enable firewalld
sudo firewall-cmd --set-default-zone=drop
sudo firewall-cmd --zone=drop --add-service=dhcpv6-client --permanent
sudo firewall-cmd --zone=drop --add-service=dns --permanent
sudo firewall-cmd --zone=drop --add-service=dns-over-quic --permanent
sudo firewall-cmd --zone=drop --add-service=dns-over-tls --permanent
sudo firewall-cmd --zone=drop --add-service=http --permanent
sudo firewall-cmd --zone=drop --add-service=htt3 --permanent
sudo firewall-cmd --zone=drop --add-service=https --permanent
sudo firewall-cmd --zone=drop --add-service=ntp --permanent
sudo firewall-cmd --zone=drop --add-service=openvpn --permanent
sudo firewall-cmd --zone=drop --add-service=samba-client --permanent
sudo firewall-cmd --zone=drop --add-service=spotify-sync --permanent
sudo firewall-cmd --zone=drop --add-service=wireguard --permanent
sudo firewall-cmd --zone=trusted --change-interface=lo --permanent

There is also a GUI for firewalld called firewall-config which should be already installed.