Arch Linux installation cheat sheet (without grub)

Szymon Niedźwiedź

Meta

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
passwd
ip a
ssh root@10.100.100.149

Installation

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/mount.sh <<EOF
#!/bin/sh
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
EOF
chmod +x /mnt/efi/mount.sh

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
127.0.0.1   localhost
::1         localhost
127.0.1.1   $hostname.localdomain $hostname
EOF

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

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

Setup users and sudo

passwd
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

/etc/mkinitcpio.d/linux.preset

# mkinitcpio preset file for the 'linux' package

#ALL_config="/etc/mkinitcpio.conf"
ALL_kver="/boot/vmlinuz-linux"
ALL_microcode=(/boot/*-ucode.img)

PRESETS=('default' 'fallback')

#default_config="/etc/mkinitcpio.conf"
default_image="/boot/initramfs-linux.img"
default_uki="/efi/EFI/Linux/arch-linux.efi"
#default_options="--splash /usr/share/systemd/bootctl/splash-arch.bmp"

#fallback_config="/etc/mkinitcpio.conf"
fallback_image="/boot/initramfs-linux-fallback.img"
#fallback_uki="/efi/EFI/Linux/arch-linux-fallback.efi"
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

exit
umount -R /mnt
reboot

After installation

Check for failed services

systemctl --failed
journalctl -p 3 -xb