# Arch Installation This document describes my ArchLinux installation steps. It skips over the preparation of the installation medium. Otherwise it mostly follows the [ArchWiki Installation Guide](https://wiki.archlinux.org/title/Installation_guide), but explicitly states some decisions: - use `systemd-boot` as the bootloader - use `NetworkManager` for network configuration - use `btrfs` as the main file system - use `LUKS` for disk encryption - use `greetd` as display manager - **try** to only use native wayland with sway as WM - use zram instead of a swap partition/file My setup is opinionated and so is this doc. [[_TOC_]] ## Pre-Installation aka things to do in the arch-iso liveboot ### Prerequisites Set keyboard layout ```console # loadkeys de-latin1 ``` Check if booted in UEFI mode ```console # ls /sys/firmware/efi/efivars ``` Check internet connectivity ```console # ip link # ping archlinux.org ``` Update system clock ```console timedatectl set-ntp true ``` ### Disk partitioning GPT partitioning scheme: | Mount point | Partition | Partition type | Size | | ----------- | --------------------- | -------------------- | ------ | | /mnt/boot | /dev/_efi-partition_ | EFI system partition | 500MiB | | /mnt | /dev/_root-partition_ | Linux x86-64 root(/) | max | Check available disks and start `fdisk` ```console fdisk -l fdisk /dev/ ``` Create GPT partition table ```md Command (m for help): _g_ ``` Create _efi-partition_ ```md Command (m for help): _n_ Partition number (1-128, default 1): __ First sector (x-y, default x): __ Last sector [...] (x-y, default y): _+500M_ Command (m for help): _t_ Selected partition 1 Partition type or alias: _1_ Changed type of partition 'Linux Filesystem' to 'EFI System'. ``` Create _root-partition_ ```md Command (m for help): _n_ Partition number (1-128, default 2): __ First sector (x-y, default x): __ Last sector [...] (x-y, default y): __ Command (m for help): _t_ Partition number (1,2, default 2): _2_ Partition type or alias: _23_ Changed type of partition 'Linux Filesystem' to 'Linux root (x86-64)'. ``` Write partitions to disk ```md Command (m for help): _w_ ``` ### Format partitions / create filesystems Format the efi partition with Fat32 ```console # mkfs.fat -F 32 /dev/ ``` Setup the root partition with LUKS ```console # cryptsetup -v --verify-passphrase --type=luks2 --hash=sha256 --key-size=512 --cipher=aes-xts-plain64 luksFormat /dev/ ``` Note: `man cryptsetup` is a really nice resource. Especially the section about the LuksHeader and the `luksHeaderBackup` command are really valuable. Mount LUKS device ```console # cryptsetup luksOpen /dev/ luks-root ``` Format luks root partition with btrfs ```console # mkfs.btrfs -L archlinuxroot /dev/mapper/luks-root ``` Create btrfs subvolumes ```console # mount -o compress=zstd /dev/mapper/luks-root /mnt # btrfs sub create /mnt/@ # btrfs sub create /mnt/@home # btrfs sub create /mnt/@pkg # btrfs sub create /mnt/@snapshots # btrfs sub create /mnt/@tmp # umount /mnt ``` Associate subvolumes and filesystem directories ```console # mount -o noatime,nodiratime,compress=zstd,subvol=@ /dev/mapper/luks-root /mnt # mkdir -p /mnt/{boot,home,var/cache/pacman/pkg,tmp,.snapshots} # mount -o noatime,nodiratime,compress=zstd,subvol=@home /dev/mapper/luks-root /mnt/home # mount -o noatime,nodiratime,compress=zstd,subvol=@pkg /dev/mapper/luks-root /mnt/var/cache/pacman/pkg # mount -o noatime,nodiratime,compress=zstd,subvol=@tmp /dev/mapper/luks-root /mnt/tmp # mount -o noatime,nodiratime,compress=zstd,subvol=@snapshots /dev/mapper/luks-root /mnt/.snapshots ``` Mount EFI partition ```console # mount /dev/ /mnt/boot ``` ## Installation ### Bootstrap & filesystemtable Bootstrap base arch install ```console # pacstrap /mnt linux linux-firmware base btrfs-progs amd-ucode git vi vim sudo networkmanager zsh ``` Generate `fstab` ```console # genfstab -U /mnt >> /mnt/etc/fstab ``` ### Basic system configuration Chroot into new system ```console # arch-chroot /mnt ``` Set hostname ```console # echo > /etc/hostname ``` Set and generate locale ```console # echo LANG=en_US.UTF-8 > /etc/locale.conf # sed -i -e 's/^#en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' -e 's/^#de_DE.UTF-8 UTF-8/de_DE.UTF-8 UTF-8/' /etc/locale.gen # locale-gen ``` Set keyboard layout ```console # echo KEYMAP=de-latin1 > /etc/vconsole.conf ``` Set time zone ```console # ln -sf /usr/share/zoneinfo/Europe/Berlin /etc/localtime # hwclock --systohc ``` Set root password ```console # passwd ``` Add btrfs and encrypt initramfs hooks to `/etc/mkinitcpio.conf` e.g.: ```ini HOOKS=(base udev autodetect modconf block encrypt btrfs filesystems keyboard fsck) ``` Regenerate initramfs ```console # mkinitcpio -p linux ``` ### Configure boot loader Install systemd-boot ```console # bootctl --path=/boot install ``` Fetch UUID of the root partition ```console # blkid -s UUID -o value /dev/ ``` Create arch boot entry `/boot/loader/entries/arch.conf` ```conf title Arch Linux linux /vmlinuz-linux initrd /amd-ucode.img initrd /initramfs-linux.img options rd.luks.name==luks-root root=/dev/mapper/luks-root rootflags=subvol=@,x-systemd.device-timeout=0 rw quiet loglevel=0 splash rd.systemd.show_status=0 rd.udev.log_level=0 rd.luks.options=discard,timeout=0 ``` Copy arch boot entry to `/boot/loader/entries/arch-fallback.conf` and set the initramfs to the fallback one. Resulting in the following ```conf title Arch Linux (fallback) linux /vmlinuz-linux initrd /amd-ucode.img initrd /initramfs-linux-fallback.img options rd.luks.name==luks-root root=/dev/mapper/luks-root rootflags=subvol=@,x-systemd.device-timeout=0 rw quiet loglevel=0 splash rd.systemd.show_status=0 rd.udev.log_level=0 rd.luks.options=discard,timeout=0 ``` Edit boot loader config `/boot/loader/loader.conf` ```conf default arch.conf timeout 3 console-mode max editor yes ``` Note: Having `editor yes` can save you from needing a bootable USB if something goes wrong in the future. Exit chroot, unmount disk, reboot ```console # exit # umount -R /mnt # reboot ``` ## Finish installation ### Enable and check networking Enable and start NetworkManager ```console # systemctl enable --now NetworkManager ``` Test network connectivity ```console # ping archlinux.org ``` ### Setup user account Create a sudo group for sudo access ```console # groupadd -r sudo ``` Use `visudo` to uncomment the following line ```sudoers # %sudo ALL=(ALL:ALL) ALL ``` Create user account with sudo and journal access. Also add user to the `pipewire` group to make use of the configured realtime limits for pipewire. ```console # useradd -m -G sudo,systemd-journal -s /bin/zsh histalek ``` Set password for useraccount ```console # passwd histalek ``` Exit out of the root session and login as user ### Install and setup personal preferences Setup my dotfiles ```console $ echo ".dotfiles" >> .gitignore $ git clone --bare $HOME/.dotfiles $ alias dotfiles='/usr/bin/git --git-dir=$HOME/.dotfiles/ --work-tree=$HOME' $ dotfiles config --local status.showUntrackedFiles no $ dotfiles checkout ``` Install and update various packages ```console $ sudo pacman -Syu --needed - < $HOME/.dotfiles/pkglist.txt ``` ### AUR Install `paru` as AUR helper ```console $ sudo pacman -Syu --needed base-devel $ git clone https://aur.archlinux.org/paru.git $ cd paru $ makepkg -si ``` Install packages from AUR ```console $ paru -Syua --needed - < $HOME/.dotfiles/pkglist-aur.txt ``` ### Flatpak Install flatpak package ```console $ sudo pacman -Syu flatpak ``` Add the flathub repo ```console $ flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo ``` Install `Flatseal` to manage flatpak permissions via GUI ```console $ flatpak install flathub com.github.tchx84.Flatseal ``` ### Setup zram Install `zram-generator` ```console $ sudo pacman -Syu zram-generator ``` Create zram config file `/etc/systemd/zram-generator.conf`, e.g.: ```ini [zram0] zram-size = min(ram, 8192) ``` ### Setup realtime limits for pipewire Create dedicated group ```console $ sudo groupadd pipewire ``` Add user to group ```console $ sudo usermod -aG pipewire histalek ``` Create `/etc/security/limits.d/95-pipewire.conf` with the following content ```console # Default limits for users of pipewire @pipewire - rtprio 95 @pipewire - nice -19 @pipewire - memlock 4194304 ``` ### (optional) Configure boot splash screen Note: As of early April 2023 `plymouth` is now in the arch community repo. The logic of the `plymouth-encrypt` hook has been merged to the `encrypt`/`sd-encrypt` hook. Install `plymouth` ```console $ sudo paru -Syu plymouth ``` Adapt mkinitcpio hooks. Add `plymouth` **after** `base systemd`. Resulting in e.g. ```ini HOOKS=(base systemd autodetect modconf kms keyboard sd-vconsole block filesystems plymouth sd-encrypt fsck) ``` Set theme for plymouth (this also regenerates the initramfs) ```console $ sudo plymouth-set-default-theme -R script ``` To get a smoother transition between plymouth and greetd place the following systemd dropin account `/etc/systemd/system/display-manager.service.d/plymouth.conf`: ``` [Unit] Conflicts=plymouth-quit.service After=plymouth-quit.service rc-local.service plymouth-start.service systemd-user-sessions.service OnFailure=plymouth-quit.service [Service] ExecStartPre=-/usr/bin/plymouth deactivate ExecStartPost=-/usr/bin/sleep 30 ExecStartPost=-/usr/bin/plymouth quit --retain-splash ``` NOTE: After updating to Kernel 6.0 plymouth didn't show up on boot. I could still type my luks passwort and proceed, but looking at a black screen was not particularly fun. I solved this by configuring [early Kernel modesetting](https://wiki.archlinux.org/title/Kernel_mode_setting#Early_KMS_start). Effectively adding `amdgpu` to the mkinitcpio modules in `/etc/mkinitcpio.conf`: ```ini MODULES=( ... amdgpu ... ) ``` ### (optional) Configure display manager These steps will use `greetd` with the `gtkgreet` greeter and will use `sway` as compositor. Install `greetd` and `greetd-gtkgreet-git` ```console $ sudo paru -Syua greetd greetd-gtkgreet-git ``` Create greetd config directory ```console $ sudo mkdir -p /etc/greetd ``` Create `/etc/greetd/environments` file with all environments that gtkgreet should be able to start, e.g.: ``` sway bash ``` Create greetd config file `/etc/greetd/config.toml`, e.g.: ```toml [terminal] # The VT to run the greeter on. Can be "next", "current" or a number # designating the VT. vt = 1 # The default session, also known as the greeter. [default_session] command = "sway --config /etc/greetd/sway-config" user = "greeter" ``` Create `/etc/greetd/sway-config` which will be used by the sway greeter session, e.g.: ```config exec "gtkgreet --layer-shell --style /etc/greetd/gtkgreet-style.css; swaymsg exit" bindsym Mod4+shift+e exec swaynag \ -t warning \ -m 'What do you want to do?' \ -b 'Poweroff' 'systemctl poweroff' \ -b 'Reboot' 'systemctl reboot' include /etc/sway/config.d/* ``` It is advisable to also set the correct output and input configuration. Either write them into the same file or place additional files into `/etc/sway/config.d/`. Optionally one can style the gtkgreet greeter with `/etc/greetd/gtkgreet-style.css`, e.g.: ```css window { background-color: rgba(0, 0, 0, 0); background-size: contain; background-position: center; color: rgba(200, 200, 200, 0.9); } box#body { background-color: rgba(50, 50, 50, 0.8); border-radius: 10px; color: rgba(250, 250, 250, 0.9); padding: 50px; } ``` Enable and start `greetd.service` ```console $ sudo systemctl enable --now greetd.service ```