I use Arch btw
Published:
I was introduced to Linux via Canonical’s advertisement program that it ran with PCWorld magazine, in which the accompanying CD had latest Ubuntu version and other software updates. This led to Linux explorations (including weirdos like BOSS Linux, Puppy Linux, Peppermint,…) in VirtualBox running on Windows XP. However, being unable to keep up with Microsoft Windows’ increasing system requirements, I ended up using Lubuntu once Windows XP reached end of life. Since then, over the last 20 years, I have had the pleasure of using the three major Linux distro families: APT (Debian/Ubuntu/Linux_Mint/Tuxedo_OS/Kali_Linux), DNF (Fedora/RHEL/CentOS), and ZYpp (SLE/openSUSE). You can read my long rants about various Linux distros in one of my old blog post. Long term Linux users might enjoy a comparison of Arch with other distros, why most of them are not endorsed by GNU, and the GNU/Linux naming controversy.
Over time, I have developed a sense of what I want and am ready to be responsible for my Thinkpad P16 :)
I learned about the process from the official guide and supplemented it with the notes by Michele Gementi, Max Pershin, Abhishek Prakash, quantinium, Daniel Wayne Armstrong, Gentoo and Ubuntu. It took around half-dozen test runs in VirtualBox over the course of a month before performing the actual installation. Here is a documentation to get started with the best operating system.
I will follow the Arch Wiki convention: The numeral or hash sign (#) indicates that the command needs to be run as root, whereas the dollar sign ($) shows that the command should be run as a regular user.
Prepararation
- Check ArchLinux website status since they are prone to DDoS attacks. I encountered this during my first ever test run of Arch Linux. Also, the services may send an initial connection reset due to the TCP SYN authentication performed by the hosting provider, but subsequent requests should work as expected.
- In the case of downtime for
archlinux.org:- Mirrors: The mirror list endpoint used in tools like
reflectoris hosted on this site. Please default to the mirrors listed in thepacman-mirrorlistpackage during an outage. - ISO: Installation image is available on a lot of the mirrors, for example the DevOps administered geomirrors. Please always verify its integrity.
- Mirrors: The mirror list endpoint used in tools like
- In the case of downtime for
aur.archlinux.org:- Packages: A mirror of AUR packages is maintained on GitHub. You can retrieve a package using:
$ git clone --branch <package_name> --single-branch https://github.com/archlinux/aur.git <package_name> - I will not use any package from
AURin this tutorial. It is similar (but superior) to the third-party repositories likePPAfor Ubuntu,COPRfor Fedora, andOBSfor openSUSE.
- Packages: A mirror of AUR packages is maintained on GitHub. You can retrieve a package using:
- In the case of downtime for
- Download the latest
archlinux-YYYY.MM.DD-x86_64.iso,sha256sums.txt, andarchlinux-YYYY.MM.DD-x86_64.iso.sigfrom the nearest mirror likemirror.arizona.edu. - Verify the integrity and authenticity of your ISO image using Linux (if Windows, use WSL).
- Integrity: Ensure the download image matches the checksum from the
sha256sums.txt$ sha256sum -c sha256sums.txtThis should output
archlinux-YYYY.MM.DD-x86_64.iso: OK. You may see “No such file or directory” for other files which we didn’t download but their checksums also included. - Authenticity: One should never use a GnuPG version just downloaded from internet to check the integrity; instead use an existing, trusted GnuPG installation, e.g., the one provided by your Linux distribution (if Windows, then use WSL).
$ gpg --auto-key-locate clear,wkd -v --locate-external-key pierre@archlinux.org $ gpg --verify archlinux-YYYY.MM.DD-x86_64.iso.sig archlinux-YYYY.MM.DD-x86_64.isoGPG might give warning
This key is not certified with a trusted signature!, but you can verify it here.
- Integrity: Ensure the download image matches the checksum from the
- Create a bootable USB drive using Ventoy; remember to verify the checksum of Ventoy itself.
- In UEFI, disable secure boot.
From chroot to root
- Boot from the Live USB drive and select Arch Linux from the
systemd-bootgreeting screen to get logged in on the first virtual console as the root user, and presented with a Zsh shell prompt. - Verify that the boot mode is UEFI by ensuring that the following command returns 64.
# cat /sys/firmware/efi/fw_platform_size - Connect to WiFi using
iwctl.# iwctl [iwd]# device list [iwd]# station <device-name> scan [iwd]# station <device-name> get-networks [iwd]# station <device-name> connect <Name of WiFi access point> [iwd]# exit $ ping -c 5 ping.archlinux.org - Ensure that the system clock is syncronized via Network Time Protocol (NTP).
# timedatectl set-ntp true # timedatectl Use
cfdiskto create the following GUID Partition Table (GPT), without hibernation feature (suspend-to-disk).Mount point Parition type Size Partition /efiEFI System Partition 1 GiB /dev/efi_system_partition[swap]Linux swap 6 GiB /dev/swap_partition/Linux Filesystem (all of the remaining space ) /dev/root_partitionCan later get the partition names using
fdisk -l.- Format the partitions using
mkfs.# mkfs.fat -F 32 /dev/efi_system_partition # mkswap /dev/swap_partition # mkfs.btrfs /dev/root_partition - Create the Btrfs filesystem layout recommended for
snapper# mount /dev/root_partition /mnt # btrfs subvolume create /mnt/@ # btrfs subvolume create /mnt/@home # btrfs subvolume create /mnt/@var_log # btrfs subvolume create /mnt/@var_cache # btrfs subvolume create /mnt/@var_spool # btrfs subvolume create /mnt/@var_tmp # btrfs subvolume create /mnt/@snapshots # btrfs subvolume list -t /mnt # lsblk --fs # umount /mnt - Mount the file systems as we prepare to chroot with Btrfs compression settings optimized for NVMe SSD (Kioxia XG8) and not using Mutt.
# mount -o noatime,compress=zstd:1,subvol=@ /dev/root_partition /mnt # mkdir -p /mnt/{home,.snapshots} /mnt/var/{log,cache,spool,tmp} # mount -o noatime,compress=zstd:1,subvol=@home /dev/root_partition /mnt/home # mount -o noatime,compress=zstd:1,subvol=@var_log /dev/root_partition /mnt/var/log # mount -o noatime,compress=zstd:1,subvol=@var_cache /dev/root_partition /mnt/var/cache # mount -o noatime,compress=zstd:1,subvol=@var_spool /dev/root_partition /mnt/var/spool # mount -o noatime,compress=zstd:1,subvol=@var_tmp /dev/root_partition /mnt/var/tmp # mount -o noatime,compress=zstd:1,subvol=@snapshots /dev/root_partition /mnt/.snapshots # mount --mkdir /dev/efi_system_partition /mnt/efi # swapon /dev/swap_partition # lsblk --fs - Use
pacstrapto create a new system installation from scratch.# pacstrap -K /mntThis installs the
basemetapackage consisting of basic tools likebash,systemd, andpacman. It also copies the LiveUSB’s mirrorlist/etc/pacman.d/mirrorlistgenerated usingreflectorto the new system. During the fifth test run I was bit by a bug in this step. - Generate
fstabfile with startup instructions# genfstab -U /mnt >> /mnt/etc/fstabCheck the resulting
/mnt/etc/fstabfile, and edit it in case of errors and various mount options likediscard=asyncandssd. - Switch to the new system’s environment
# arch-chroot /mnt- Set up the time zone.
# ls /usr/share/zoneinfo/ # ls /usr/share/zoneinfo/<Zone>/ # ln -sf /usr/share/zoneinfo/<Zone>/<Subzone> /etc/localtime # hwclock --systohc - Configure correct region and language specific formatting.
- Install a console text-editors like
nano:# pacman -S nano - Use
nanoto edit/etc/locale.genand uncommenten_US.UTF-8 UTF-8. - Generate the locales.
# locale-gen - Use
nanoto create configuration file/etc/locale.confand writeLANG=en_US.UTF-8in it.
- Install a console text-editors like
- Network configuration.
- Use
nanoto create/etc/hostnameand write<PC-Name>in it. - Use
nanoto edit/etc/hostsand add the following to it127.0.0.1 localhost ::1 localhost 127.0.1.1 <PC-Name> - Install and enable network manager to run on boot.
# pacman -S networkmanager # systemctl enable NetworkManager
- Use
- Create a new
initramfs(initial RAM file system)- Install userspace utilities for the Btrfs file system (
btrfs-progs) and Linux kernellinuxwithlinux-ltsas a fallback option. If presented with options for initramfs, choosemkinitcpio. Note that trying to install kernel withoutbtrfs-progswill lead to error whenmkinitcpioruns thefsckhook. - Install kernel firmware (
linux-firmware) along with additional firmware for Intel CPU (intel-ucode), Intel iGPU (mesa,vulkan-intel), NVIDIA dGPU (nvidia,nvidia-utils), and Dolby Atmos (pipewire,pipewire-alsa,pipewire-pulse,pipewire-jack,wireplumber). - Re-run
mkinitcpioto be sure that we have an error free initial ramdisk environment.# mkinitcpio -PNote that every time a kernel is installed or upgraded, a pacman hook automatically generates a preset file saved in
/etc/mkinitcpio.d/and-Poption process all presets contained in/etc/mkinitcpio.d.
- Install userspace utilities for the Btrfs file system (
- Set root password using
passwdcommand. - Install a btrfs-friendly bootloader, like GRUB.
# pacman -S grub efibootmgr # grub-install --target=x86_64-efi --efi-directory=/efi --bootloader-id=GRUB # grub-mkconfig -o /boot/grub/grub.cfgKernel packages are installed under the
/usr/lib/modules/path and subsequently used to copy the vmlinuz executable image to/boot/. - We can use the bootloader to switch between
linuxandlinux-ltskernel. But will setlinuxas the default option by editing/etc/default/grub:GRUB_DISABLE_SUBMENU=y GRUB_DEFAULT="Arch Linux, with Linux linux"Regenerate your configuration file with
grub-mkconfig. - Exit the chroot environment by typing
exitor pressing Ctrl + d.
- Set up the time zone.
- Manually unmount all the partitions
# umount -R /mnt - Reboot (or
poweroff) the system and remove the installation media# reboot
From superuser to user
- Login into the new system with the root account (superuser).
- Connect to WiFi using
nmtuiornmcli.# nmcli device wifi connect <Name of WiFi access point> password <password> - Pacman configuration to automatically update mirrors and periodically clear out cache.
# pacman -S pacman-contrib # systemctl enable --now paccache.timer # pacman -S reflector # systemctl enable --now reflector.timer - Install
manto have offline access to Arch Linx documentation.# pacman -S man-db - Create a user and add to administration group (
wheel) withsudoaccess. Note that logging in using root account is disabled for GUI.# useradd -mG wheel <user-name> # passwd <user-name> # pacman -S sudo # EDITOR=nano visudoThe last command opens the
/etc/sudoersfile usingnano; look for a line which says something likeUncomment to allow members of group wheel to execute any commandand uncomment exactly the line BELOW it, by removing the#. This will grant superuser priviledges to your user. - Check NVIDIA configuration by ensuring that the Direct Rendering Manager (DRM) is enabled.
# cat /sys/module/nvidia_drm/parameters/modesetThis should return
Y. - Install KDE with Wayland support following advice from the KDE documentation and Arch dependency tree of
plasma-desktop. We have consciously excludeddiscoverfrom KDE because it can lead to partial upgrades which are unsupported in Arch.- base:
plasma-{desktop,pa,nm,systemmonitor,firewall},kscreen,bluedevil,powerdevil,tlp - keyring (PAM):
kwalletmanager,kwallet-pam - terminal (otherwise will need to use
tty):konsole - file manager:
dolphin,dolphin-plugins,kdegraphics-thumbnailers,ffmpegthumbs - XDG Desktop Portal (Wayland and Firefox integration):
xdg-desktop-portal-gtk,xdg-desktop-portal-kde - Theme consistency (GTK in Qt):
breeze-gtk,kde-gtk-config# pacman -S <space separated list of packages>You may be prompted to choose between
ffmpegorgstreamerbackend forqt6-multimedia. I choseffmpegbecause that seems to be the default.
- base:
- Install Simple Desktop Display Manager (SDDM).
# pacman -S sddm # systemctl enable sddm # pacman -S --needed sddm-kcm - Reboot to finalize installation.
# reboot
Personalization
- Login using user account in SDDM.
- Check if any systemd services have failed or errors in the log files located in
/var/log/.$ systemctl --failed $ journalctl -b -p 3 - Go to
Settings→Colors & Themes→Login Screen (SDDM)→Breeze→Change Background→Apply. - Install essential software using the package manager.
- Browser:
firefox(along with extensions: uBlock Origin, Privacy Badger, Decentraleyes, ClearURLs, and password manager) - Document viewer:
okular,ebook-tools,kdegraphics-mobipocket,unarchiver - Image viewer:
gwenview,kimageformats,qt6-imageformats - Video player (mpv and yt-dlp based):
haruna,yt-dlp - Archiving tool:
ark,7zip - Screenshot tool:
spectacle - Calculator:
kalk - Text editor:
kate - File searching tool:
kfind - Messaging:
signal-desktop - GPU manager (NVIDIA):
nvidia-settings - Webcam controls (LogiTune):
cameractrls - Wireless mouse (LogiBolt):
solaar - IDE:
emacs-wayland
- Browser:
- Battery care configuration using
tlp.$ sudo systemctl enable --now tlp.service $ sudo tlp-stat -s $ sudo tlp-stat -bWe can configure
tlpby editing battery care settings in/etc/tlp.conf. - Configure Git and GitHub.
$ sudo pacman -S git openssh- Set the name and email for git commits. Also set default editor and push behavior.
$ git config --global user.name "Your Name" $ git config --global user.email "your.email@github.com" $ git config --global core.editor "nano -w" $ git config --global push.default simple - Configure SSH for GitHub interaction:
- Generate a new public and private SSH key pair using OpenSSH.
- Add SSH public key to the GitHub account.
- Set the name and email for git commits. Also set default editor and push behavior.
- Configure
rclonefor Google Drive backup.$ sudo pacman -S rclone- Create your own Google Drive OAuth2 client ID for rclone:
- Log into the Google API Console with your Google account. It doesn’t matter what Google account you use. (It need not be the same account as the Google Drive you want to access.
- Select a project or create a new project.
- Under “ENABLE APIS AND SERVICES” search for “Drive”, and enable the “Google Drive API”.
- Click “Oauth Consent Screen” in the left panel and select user type “External”. Then add Application name (anything you want) and save.
- Click “Credentials” in the left panel. Then click on “+ CREATE CREDENTIALS” button at the top of the screen, then select “OAuth client ID”. Select Application type as “Desktop app”, enter whaever client anme you want and click create.
- It will show you a client ID and client secret. Use these values in rclone config.
- Now configure rclone for Google Drive via Terminal:
rclone configand follow the steps. Remember to use the Client ID and client secret we created above. Since we created this API for personal use, we won’t be submitting it for verfication. Hence don’t be alarmed by the very scary confirmation screen shown when we connect via your browser for rclone to be able to get its token-id. Also, if you want to fetch Google Docs as links (instead of converting them to .odt etc) from Google Drive, in “advance-config” set “export-formats” to “link.html”. - Sync files using “copy” and NOT “sync”:
rclone copy source:path dest:path [flags]. For example, to sync all files from “New Folder” Google Drive (named: Drive) to PC (folder: home) and view the progress, type:rclone copy Drive:"New Folder" /home -P. Google Drive tend to have duplicate files since it allows same names files in same folder, in that case use dedupe to delete all duplicate files.
- Create your own Google Drive OAuth2 client ID for rclone:
- Configure snapper for automatic
/snapshots per the Wiki.$ sudo su # pacman -S snapper- Unmount
/.snapshots# btrfs subvolume list -t / # lsblk --fs # umount /.snapshots # rm -r /.snapshots - Create a new snapper configuration named
rootfor the Btrfs subvolume at/.# snapper -c root create-config / # btrfs subvolume list -t / # btrfs subvolume delete /.snapshots # mkdir /.snapshots # mount -o noatime,compress=zstd:1,subvol=@snapshots /dev/root_partition /.snapshotsThis will create a configuration file at
/etc/snapper/configs/root. When you delete config file, then also delete its entry from/etc/conf.d/snapperto readSNAPPER_CONFIGS="". - Make this mount permanent by adding an entry to
fstab.# btrfs subvolume list -t / # lsblk --fs # blkid # nano /etc/fstab # mount -a # chmod 750 /.snapshots # chown :wheel /.snapshots - Use systemd timer units for automatic timeline snapshots and cleanup.
# systemctl enable --now snapper-timeline.timer # systemctl enable --now snapper-cleanup.timer # systemctl edit --full snapper-timeline.timer # systemctl edit --full snapper-cleanup.timerFor taking snapshots use realtime timer
OnCalendar=hourlyinsnapper-timeline.timerunit and for cleanup use monotomic timerOnBootSec=10mandOnUnitActiveSec=1hinsnapper-cleanup.timerunit. Unlike Timeshift, we will not use cron job. - Set snapshot limits by editing
/etc/snapper/configs/root# limit for number cleanup NUMBER_MIN_AGE="1800" NUMBER_LIMIT="10" NUMBER_LIMIT_IMPORTANT="5" # limits for timeline cleanup TIMELINE_MIN_AGE="1800" TIMELINE_LIMIT_HOURLY="5" TIMELINE_LIMIT_DAILY="7" TIMELINE_LIMIT_WEEKLY="0" TIMELINE_LIMIT_MONTHLY="0" TIMELINE_LIMIT_YEARLY="0" # limits for empty pre-post-pair cleanup EMPTY_PRE_POST_MIN_AGE="1800"Here 1800 seconds = 30 min.
- We can use the
grub-btrfsdaemon to automatically update GRUB upon snapshot creation or deletion, and avoid dependency on LiveUSB for restoring snapshots.# pacman -S grub-btrfs inotify-tools # systemctl enable --now grub-btrfsdThen enable booting into read-only snapshots using overlay filesystem by adding
grub-btrfs-overlayfsto the end of theHOOKSarray in/etc/mkinitcpio.confand regenerating theinitramfs.# nano /etc/mkinitcpio.conf # mkinitcpio -PIf you try to boot from these read-only snapshots available in GRUB menu, the following warning/error might appear:
********************* WARNING ********************* * The root device is not configured to be mounted * * read-write! It may be fsck'd again later. * *************************************************** [FAILED] Failed to start Remount Root and Kernel File Systems.Here the
WARNINGjust confirms that our snapshot is read-only and[FAILED]confirms that systemd failed to mount the underlying read-only root filesystem. Despite this “failure” message, the boot process should continue using OverlayFS’s temporary read-write upper layer, leaving the original Btrfs snapshot untouched. - Use
snap-pacto make pacman automatically use snapper to create pre/post snapshots.# pacman -S snap-pac - Testing snapshots by installing
inxi.# pacman -S inxi # inxi -Fxz # snapper -c root list
- Unmount
- Reboot and check if things if the things are as expected.
Maintainance
- When refreshing the package database, always do a full upgrade.
# pacman -Syu - Uninstall pacakge along with its dependecies.
# pacman -Rs <package> - Recursively remove orphaned packages that were installed as a dependency but now, no other packages depend on them.
# pacman -Qdtq | pacman -Rns - - Check list all foreign packages that are no longer be in the remote repositories, but still on your local system.
# use pacman -Qm.This list will also include packages that have been installed manually (e.g., from the
AUR). - Use
nvmeto probe the health of SSD.# pacman -S nvme-cli # nvme smart-log /dev/root_partition - To view a list of snapshots under
rootconfigurations.# snapper -c root list - If GUI fails then can use LiveUSB arch-chroot or Desktop environment’s tty.
- To restore
/using one of snapper’s snapshots, we need access to OverlayFS (either via LiveUSB orgrub-btrfs) and follow these steps.- Mount the toplevel subvolume.
# fdisk -l # mount /dev/root_partition /mnt # lsblk --fs # btrfs subvolume list -t /mnt - Move
@to another location (e.g./@.broken) to save a copy of the current system.# mv /mnt/@ /mnt/@.broken # btrfs subvolume list -t /mnt - Find the
numberof the snapshot that you want to recover:# grep -r '<date>' /mnt/@snapshots/*/info.xml - Create a read-write snapshot of the read-only snapshot snapper took:
# btrfs subvolume snapshot /mnt/@snapshots/<number>/snapshot /mnt/@ - Check
fstabis correct.# cat /mnt/etc/fstab - Unmount the top-level subvolume (ID=5), then mount
@to/mntand your ESP or boot partition to the appropriate mount point.# umount /mnt # mount -o noatime,compress=zstd:1,subvol=@ /dev/root_partition /mnt # mount /dev/efi_system_partition /mnt/efi - If using LiveUSB then Change root to your restored snapshot before regenerating initramfs image.
# arch-chroot /mnt # mkinitcpio -P # exit # reboot - If everything is as expected then delete the broken snapshot.
# btrfs subvolume delete /@.broken
- Mount the toplevel subvolume.
- Vendor firmware updates (like UEFI)
# pacman -S fwupd udisks2 # fwupdmgr get-devices
