If you want a fast, modern, and secure Linux setup, Arch Linux with BTRFS on an encrypted disk is a great combination. BTRFS gives you snapshots, transparent compression, and copy-on-write semantics. LUKS encryption ensures your data is safe at rest. Together they make a robust foundation for a daily driver.
This guide walks through a complete installation from live ISO to a bootable, encrypted Arch system. It assumes UEFI, an SSD, and uses GRUB as the bootloader. No swap partition is needed — we’ll use a swap file instead.
Prerequisites
- A bootable Arch Linux USB
- An internet connection (wired or Wi-Fi)
- A target disk (the guide uses
/dev/sda— adjust to match your system)
Step 1: Boot Environment Setup
Set a Readable Font
The default console font is small. Make it easier on your eyes:
setfont ter-u20n
Verify UEFI Mode
cat /sys/firmware/efi/fw_platform_size
64→ 64-bit UEFI (most common, all bootloaders supported)32→ 32-bit UEFI (limited to systemd-boot)- File missing → likely booted in BIOS/legacy mode
This guide assumes 64-bit UEFI.
Step 2: Network
Wi-Fi (skip if on ethernet)
iwctl --passphrase [password] station wlan0 connect [network-name]
Verify Connectivity
ping -c5 archlinux.org
Step 3: System Clock and Mirrors
Sync the Clock
timedatectl set-ntp true
Set Fast Mirrors with Reflector
reflector --country US --latest 5 --sort rate --save /etc/pacman.d/mirrorlist
pacman -Syy
Tweak pacman.conf
Enable parallel downloads and color output for a faster, prettier experience:
nano /etc/pacman.conf
Find the [options] section and set:
Color
ParallelDownloads = 5
Save with Ctrl+O, exit with Ctrl+X.
Step 4: Partition the Disk
Identify Your Disk
lsblk
Partition with cfdisk
cfdisk /dev/sda
If prompted for a label type, select gpt.
Create two partitions:
| Partition | Size | Type | Purpose |
|---|---|---|---|
/dev/sda1 | 477M | EFI System | Boot/EFI |
/dev/sda2 | Remaining | Linux filesystem | Encrypted root |
No swap partition is needed — a swap file on BTRFS will be used instead.
Select Write, type yes, then Quit.
Confirm the layout:
lsblk
Step 5: Encryption and Filesystem Setup
Format the EFI Partition
mkfs.fat -F32 /dev/sda1
Encrypt the Root Partition
cryptsetup --cipher=aes-xts-plain64 --hash=sha512 --use-random --verify-passphrase luksFormat /dev/sda2
You’ll be asked to confirm with YES and set a passphrase. Don’t lose this passphrase — there is no recovery.
Open the Encrypted Partition
cryptsetup luksOpen /dev/sda2 archlinux
This maps the decrypted device to /dev/mapper/archlinux.
Format as BTRFS
mkfs.btrfs /dev/mapper/archlinux
Step 6: Create BTRFS Subvolumes
BTRFS subvolumes let you take granular snapshots and exclude certain directories (like logs or cache) from rollbacks.
Mount and Create Subvolumes
mount /dev/mapper/archlinux /mnt
cd /mnt
btrfs subvolume create @
btrfs subvolume create @home
btrfs subvolume create @cache
btrfs subvolume create @images # libvirt VM disk images — skip if you're not running VMs
btrfs subvolume create @tmp
btrfs subvolume create @log
btrfs subvolume create @snapshots
cd
umount /mnt
Mount Subvolumes with Optimized Options
The mount options used here are tuned for SSDs:
noatime— no access time writes, reduces wearcompress=zstd— transparent compression (good ratio + speed)ssd— enables SSD-aware optimizationsdiscard=async— async TRIM support
mount -o noatime,space_cache=v2,compress=zstd,ssd,discard=async,subvol=@ /dev/mapper/archlinux /mnt
mkdir -p /mnt/{boot/efi,home,.snapshots,tmp,var/{cache,log,lib/libvirt/images}}
mount -o noatime,space_cache=v2,compress=zstd,ssd,discard=async,subvol=@home /dev/mapper/archlinux /mnt/home
mount -o noatime,space_cache=v2,compress=zstd,ssd,discard=async,subvol=@snapshots /dev/mapper/archlinux /mnt/.snapshots
mount -o noatime,space_cache=v2,compress=zstd,ssd,discard=async,subvol=@tmp /dev/mapper/archlinux /mnt/tmp
mount -o noatime,space_cache=v2,compress=zstd,ssd,discard=async,subvol=@cache /dev/mapper/archlinux /mnt/var/cache
mount -o noatime,space_cache=v2,compress=zstd,ssd,discard=async,subvol=@log /dev/mapper/archlinux /mnt/var/log
mount -o noatime,space_cache=v2,compress=zstd,ssd,discard=async,subvol=@images /dev/mapper/archlinux /mnt/var/lib/libvirt/images
mount /dev/sda1 /mnt/boot/efi
Step 7: Install the Base System
pacstrap -K /mnt base base-devel linux linux-firmware git vim openssh amd-ucode reflector
Swap
amd-ucodeforintel-ucodeif you’re on Intel hardware.
Step 8: Generate fstab
genfstab -U /mnt >> /mnt/etc/fstab
Review the output to confirm all subvolumes and the EFI partition are listed:
cat /mnt/etc/fstab
Step 9: Chroot into the New System
arch-chroot /mnt
Everything from here runs inside your new installation.
Step 10: Configure the Initramfs
The initramfs needs to know about BTRFS and LUKS so it can unlock the disk at boot.
vim /etc/mkinitcpio.conf
Edit the following lines:
MODULES=(btrfs)
HOOKS=(base udev autodetect modconf kms keyboard keymap consolefont block encrypt filesystems fsck)
Key hooks:
encrypt— prompts for the LUKS passphrase at bootbtrfsin MODULES — ensures BTRFS is available in the initramfs
Rebuild the initramfs:
mkinitcpio -p linux
Step 11: Localization and Time
Timezone
ln -sf /usr/share/zoneinfo/America/Chicago /etc/localtime
hwclock --systohc --utc
Adjust the timezone path to match your region.
Locale
vim /etc/locale.gen
Uncomment en_US.UTF-8 UTF-8, then generate:
locale-gen
echo LANG=en_US.UTF-8 > /etc/locale.conf
Step 12: Hostname and Hosts File
echo arch-base-grub > /etc/hostname
vim /etc/hosts
Add:
127.0.0.1 localhost
::1 localhost
127.0.1.1 arch-base-grub.localdomain arch-base-grub
Step 13: Set Root Password
passwd
Step 14: pacman Configuration
vim /etc/pacman.conf
In the [options] section:
Color
CheckSpace
VerbosePkgLists
ParallelDownloads = 5
ILoveCandy
Also uncomment the [multilib] section and its Include line to enable 32-bit package support (needed for Steam, Wine, etc.).
Step 15: Install Additional Packages
This installs everything needed for a full desktop-ready system including audio, networking, Bluetooth, printing, GPU drivers, virtualization, and more:
pacman -S grub efibootmgr grub-btrfs networkmanager network-manager-applet dialog \
wpa_supplicant linux-headers alsa-utils pipewire pipewire-alsa pipewire-pulse pipewire-jack \
bash-completion zsh zsh-completions firewalld terminus-font cups btrfs-progs \
xf86-video-amdgpu xf86-video-nouveau mesa lib32-mesa vulkan-radeon lib32-vulkan-radeon \
libva-mesa-driver lib32-libva-mesa-driver mesa-vdpau lib32-mesa-vdpau \
os-prober mtools dosfstools avahi xdg-user-dirs xdg-utils gvfs gvfs-smb nfs-utils \
inetutils dnsutils bluez dnsmasq openbsd-netcat ipset nss-mdns acpid ntfs-3g \
pacman-contrib zip unzip fastfetch duf haveged exfatprogs \
qemu virt-manager virt-viewer edk2-ovmf bridge-utils vde2 iptables-nft ebtables libguestfs
Tailor this list to your needs. The GPU drivers here cover AMD and Nouveau (NVIDIA open). Remove what you don’t need.
Step 16: Install and Configure GRUB
First, edit /etc/default/grub to pass the encrypted partition UUID and the BTRFS root subvolume to the kernel. This must happen before generating the GRUB config:
vim /etc/default/grub
Set the following line:
GRUB_CMDLINE_LINUX="cryptdevice=UUID=$(blkid -s UUID -o value /dev/sda2):archlinux root=/dev/mapper/archlinux rootflags=subvol=@"
cryptdevice— tells GRUB which partition to unlock and what name to give the mapped deviceroot— points to the decrypted devicerootflags=subvol=@— tells BTRFS to mount the@subvolume as root; without this, the initramfs mounts the top-level BTRFS volume and the system won’t boot correctly
Then install GRUB and generate the config:
grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=ArchLinux
grub-mkconfig -o /boot/grub/grub.cfg
Step 17: Enable System Services
systemctl enable NetworkManager
systemctl enable bluetooth
systemctl enable sshd
systemctl enable reflector.timer
systemctl enable avahi-daemon
systemctl enable firewalld.service
systemctl enable cups.service
systemctl enable fstrim.timer
systemctl enable acpid
fstrim.timer runs periodic TRIM on your SSD — important for long-term performance.
Step 18: Create a User
Add the libvirt Group (for VM management)
groupadd --system libvirt
Create Your User
useradd -m -G sys,log,network,floppy,scanner,power,rfkill,users,video,storage,optical,lp,audio,wheel,adm,libvirt -s /bin/zsh yourusername
passwd yourusername
Grant sudo Access
export VISUAL=vim
visudo /etc/sudoers
Uncomment the line that allows wheel group members to use sudo:
%wheel ALL=(ALL:ALL) ALL
Step 19: Reboot
Exit the chroot and unmount everything:
exit
umount -R /mnt
reboot
Remove the USB drive when the system powers down. On the next boot, GRUB will appear, then prompt you for your LUKS passphrase to unlock the disk.
What You Get
After a successful boot you’ll have:
- Full disk encryption via LUKS2 — data is protected at rest
- BTRFS with subvolumes for clean snapshot boundaries
- zstd compression — transparent, fast compression saving disk space
- SSD-optimized mount options and async TRIM
- Pipewire for modern audio
- NetworkManager for easy network management
- Firewalld for a default-deny firewall
- KVM/QEMU virtualization stack ready to go
From here you can install a desktop environment, configure your shell, and set up snapper or Timeshift for automated BTRFS snapshots.
Based on a personal installation walkthrough. Tested on hardware with AMD GPU and NVMe SSD.