Szymon Niedźwiedź


This cheatsheet is based on my previous cheatsheet, but uses EFI and UKI instead of GRUB.

Enable SSH for remote access

systemctl start sshd.service
ip a
ssh root@


Check if UEFI is enabled

ls /sys/firmware/efi/efivars

Update time

timedatectl set-ntp true
timedatectl status

export disk variables

export disk="/dev/vda"
export disk_boot=/dev/vda1
export disk_luks=/dev/vda2
export disk="/dev/sda"
export disk_boot=/dev/sda1
export disk_luks=/dev/sda2
export disk="/dev/nvme1n1"
export disk_boot=/dev/nvme1n1p1
export disk_luks=/dev/nvme1n1p2

Wipe disk that is going to be used

cryptsetup open --type plain -d /dev/urandom $disk target
dd if=/dev/zero of=/dev/mapper/target bs=1M status=progress oflag=direct
cryptsetup close target

Partition 1 - EFI partition (ESP) - size 512MiB, code ef00

Partition 2 - encrypted partition (LUKS) - remaining storage, code 8309

sgdisk --list-types
sgdisk -n 0:0:+512MiB -t 0:ef00 -c 0:esp $disk
sgdisk -n 0:0:0 -t 0:8309 -c 0:luks $disk
partprobe $disk
sgdisk -p $disk

Format disk

cryptsetup --type luks1 -v -y luksFormat ${disk_luks}
cryptsetup open ${disk_luks} cryptdev
mkfs.vfat -F32 -n ESP ${disk_boot}
mkfs.btrfs -L archlinux /dev/mapper/cryptdev
mount /dev/mapper/cryptdev /mnt
btrfs subvolume create /mnt/@
btrfs subvolume create /mnt/@home
btrfs subvolume create /mnt/@snapshots
btrfs subvolume create /mnt/@cache
btrfs subvolume create /mnt/@libvirt
btrfs subvolume create /mnt/@log
btrfs subvolume create /mnt/@tmp
umount /mnt
export sv_opts="rw,noatime,compress-force=zstd:1,space_cache=v2"
mount -o ${sv_opts},subvol=@ /dev/mapper/cryptdev /mnt
mkdir -p /mnt/{home,.snapshots,var/cache,var/lib/libvirt,var/log,var/tmp}
mount -o ${sv_opts},subvol=@home /dev/mapper/cryptdev /mnt/home
mount -o ${sv_opts},subvol=@snapshots /dev/mapper/cryptdev /mnt/.snapshots
mount -o ${sv_opts},subvol=@cache /dev/mapper/cryptdev /mnt/var/cache
mount -o ${sv_opts},subvol=@libvirt /dev/mapper/cryptdev /mnt/var/lib/libvirt
mount -o ${sv_opts},subvol=@log /dev/mapper/cryptdev /mnt/var/log
mount -o ${sv_opts},subvol=@tmp /dev/mapper/cryptdev /mnt/var/tmp
mkdir /mnt/efi
mount ${disk_boot} /mnt/efi
pacman -Syy

cat > /mnt/efi/ <<EOF
set -x
set -e
export disk=$disk"
export disk_boot=$disk_boot
export disk_luks=$disk_luks
cryptsetup luksOpen \$disk_luks cryptdev
export sv_opts="rw,noatime,compress-force=zstd:1,space_cache=v2"
mount -o \${sv_opts},subvol=@ /dev/mapper/cryptdev /mnt
mount -o \${sv_opts},subvol=@home /dev/mapper/cryptdev /mnt/home
mount -o \${sv_opts},subvol=@snapshots /dev/mapper/cryptdev /mnt/.snapshots
mount -o \${sv_opts},subvol=@cache /dev/mapper/cryptdev /mnt/var/cache
mount -o \${sv_opts},subvol=@libvirt /dev/mapper/cryptdev /mnt/var/lib/libvirt
mount -o \${sv_opts},subvol=@log /dev/mapper/cryptdev /mnt/var/log
mount -o \${sv_opts},subvol=@tmp /dev/mapper/cryptdev /mnt/var/tmp
mount \${disk_boot} /mnt/efi
chmod +x /mnt/efi/

install base packages and files

# sort by freshest
reflector --verbose --protocol https --latest 10 --sort rate \
          --country Germany --country Germany --save /etc/pacman.d/mirrorlist

choose microcode variant

export microcode="intel-ucode"
export microcode="amd-ucode"

run pacstrap

pacstrap /mnt base base-devel ${microcode} btrfs-progs linux linux-firmware \
              bash-completion cryptsetup htop man-db mlocate neovim networkmanager \
              openssh pacman-contrib pkgfile reflector sudo terminus-font tmux neovim

generate /etc/fstab

genfstab -U -p /mnt >> /mnt/etc/fstab

chroot into base installation

arch-chroot /mnt /usr/bin/bash

Continue installation inside chroot

ln -sf /usr/share/zoneinfo/Europe/Warsaw /etc/localtime
hwclock --systohc

export hostname="lightspeed-vm"

echo "$hostname" > /etc/hostname
cat > /etc/hosts <<EOF   localhost
::1         localhost   $hostname.localdomain $hostname

export locale="en_US.UTF-8"
sed -i "s/^#\(${locale}\)/\1/" /etc/locale.gen
echo "LANG=${locale}" > /etc/locale.conf

echo "EDITOR=nvim" > /etc/environment && echo "VISUAL=nvim" >> /etc/environment

Setup users and sudo

useradd -m -G wheel -s /bin/bash mono
passwd mono
sed -i "s/# %wheel ALL=(ALL:ALL) ALL/%wheel ALL=(ALL:ALL) ALL/" /etc/sudoers
pacman -S  efibootmgr

set path to root of fs subvolume as default mountpoint (otherwise initramfs won’t mount correctly and chrooting will be required to fix this issue)

# btrfs subvolume list -p /
# btrfs subvolume set-default 256 /
# mkdir -p /etc/cmdline.d/

get root uuid

ls -alh /dev/disk/by-uuid

get cryptdevice uuid

blkid -s UUID -o value ${disk_luks}

setup kernel command-line

# /etc/cmdline.d/root.conf
root=UUID=9cd50cd2-ec6e-4298-b476-2c2fa314d046 loglevel=10 quiet cryptdevice=UUID=36995d9d-77b5-46d6-ad11-7d74021af29f:cryptdev


# mkinitcpio preset file for the 'linux' package


PRESETS=('default' 'fallback')

#default_options="--splash /usr/share/systemd/bootctl/splash-arch.bmp"

fallback_options="-S autodetect"

File that will open

# /etc/mkinitcpio.conf
MODULES=(btrfs nvme nvme_core)
HOOKS=(base udev keyboard autodetect keymap consolefont modconf block encrypt filesystems fsck)

Recreate the initramfs image

mkdir -p /efi/EFI/Linux
mkinitcpio -P
# ${disk_boot} may be undeclared after chrooting
efibootmgr -c -d ${disk_boot} -l '\EFI\Linux\arch-linux.efi' -L "ArchLinux"

install DE and basic services

pacman -S lightdm lightdm-gtk-greeter plasma-meta
pacman -S networkmanager firefox terminator rsync kate dolphin
systemctl enable lightdm
systemctl enable NetworkManager
systemctl enable sshd.service
systemctl enable fstrim.timer

umount -R /mnt

After installation

Check for failed services

systemctl --failed
journalctl -p 3 -xb