My First Arch Linux Installation

During a specific vacation from college, I figured I should try installing Arch Linux just because I was curious (and I wanted to say I use Arch btw).

My expectations

  • Learn! Since it’s the first time I’m installing Arch Linux in a physical machine, I want to learn as much as I can, and write them down as much as possible
  • Minimal installation
  • Disk encryption
  • Snapshots

What you should expect (disclaimer)

This is not a tutorial (although I wrote it as a tutorial for me). This is just a report from my first time installing Arch in a physical computer.

You can use it as a kickstart for your own Arch install, or just see how I take notes.

Make sure to double check the information since they might not be completely up-to-date or outlined in a more simplistic way compared to the reality (always check the Arch Wiki).

Anyways, if you have any doubt or suggestions, make sure you reach me.

First things first

Installation

You can change the keyboard layout as well. Layouts can be listed with:

localectl list-keymaps

Since my laptop is ABNT-2 (Brazil’s default), I can change it with:

loadkeys br-abnt2

Also, this is completely optional, but I like to change the font:

setfont Lat2-Terminus16

Network and Internet connection

Since I was using wired connection, I didn’t need to setup anything, but, if it’s not your case (something’s not right or you’re using wireless connection, check this).

  • To test if you’re connected to the internet, ping any website:
  ping archlinux.org

System clock

Now it’s time to check if everything is right running timedatectl.

  • You can list the timezones with:
timedatectl list-timezones
  • Then you can select your timezone, for example America/Sao_Paulo:
timedatectl set-timezone America/Sao_Paulo

Disk partitioning

  • Identify the disk you’ll be partitioning
fdisk -l
  • Use the fdisk specifying the disk
fdisk /dev/sda

Assuming you’re in fdisk:

  • To create a partition table, type g
  • Now in order to create the boot partition, now type n
    • Select the first sector (kind of the starting point of the partition), the default (for the first partition) is 2048
    • Select the last sector. There are a few tips on how to select them:
      • Use the + symbol by the partition size
      • The size can be specified in kibibytes (K), mebibytes (M), gibibytes (G), tebibytes (T), or pebibytes (P)
      • Since it’s the boot partition I’ll set 1GiB with +1G
    • The default type for newly created partitions is Linux Filesystem
    • Since it’s the boot partition, the type has to be changed. For that, type t
      • Then specify the type (type L to list all available types)
      • The EFI System type is 1
  • Repeat this process as needed in order to create the desired partitions
    • Personally, I just create another partition with the rest of the available space (all defaults)
  • When you finish creating the partitions, type w to write changes to the disk

Create a FAT 32 system on the EFI partition (in my casse it’s /dev/sda1):

mkfs.fat -F 32 /dev/sda1

System encryption

Initialize encryption on the Linux Filesystem partition. It’ll prompt a password to encrypt your system:

cryptsetup -y -v luksFormat /dev/sda2

Map /dev/sda2 to /dev/mapper/cryptroot:

cryptsetup open /dev/sda2 root

BTRFS parititioning and Swapfile

Create BTRFS on the encrypted Linux Filesystem partition:

mkfs.btrfs /dev/mapper/cryptroot

Now mount it:

mount /dev/mapper/cryptroot /mnt

cd to /mnt and create the subvolumes as recommended for use with snapper (a program I found on Cody Hou’s Arch installation, reference below):

cd /mnt
btrfs subvolume create @
btrfs subvolume create @home
btrfs subvolume create @snapshots
btrfs subvolume create @var_log
btrfs subvolume create @swap

Unmount root and remount the subvolumes and the boot partition. noatime is used for better performance zstd as file compression:

cd
umount /mnt
mount -o noatime,compress=zstd,space_cache=v2,subvol=@ /dev/mapper/cryptroot /mnt
mkdir -p /mnt/{boot,home,.snapshots,var/log,swap}
mount -o noatime,compress=zstd,space_cache=v2,subvol=@home /dev/mapper/cryptroot /mnt/home
mount -o noatime,compress=zstd,space_cache=v2,subvol=@snapshots /dev/mapper/cryptroot /mnt/.snapshots
mount -o noatime,compress=zstd,space_cache=v2,subvol=@var_log /dev/mapper/cryptroot /mnt/var/log
mount -o noatime,subvol=@swap /dev/mapper/cryptroot /mnt/swap
mount /dev/sda1 /mnt/boot

Create a swap file. Change the count parameter in order to specify the size of the swap file:

cd /mnt/swap
chattr +C /mnt/swap
dd if=/dev/zero of=./swapfile bs=1M count=8192 status=progress
chmod 0600 ./swapfile

Now you can install the essential packages in your system. (replace intel-ucode with intel-ucodeif you’re using an Intel processor):

pacstap -K /mnt base base-devel linux linux-firmware amd-ucode vim git networkmanager btrfs-progs dosfstools e2fsprogs exfat-utils ntfs-3g smartmontools dialog man-db man-pages texinfo pacman-contrib

Configuring the system

Fstab

Generate fstab:

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

Chroot

Change root into the system:

arch-chroot /mnt

Time

Set the time zone accordingly (you can look in /usr/share/zoneinfo for your region and city):

ln -sf /usr/share/zoneinfo/America/Sao_Paulo /etc/localtime

Run hwclock to generate /etc/adjtime:

hwclock --systohc

Localization

Edit /etc/locale.gen and uncomment the needed UTF-8 locales (In my case, I’ll uncomment en_US.UTF-8 UTF-8 and pt_BR.UTF-8 UTF-8):

vim /etc/locale.gen

After you uncomment the locales, you have to generate the locales:

locale-gen

Now you can create /etc/locale.conf file:

vim /etc/locale.conf

And set the LANG variable accordingly:

LANG=pt_BR.UTF-8

Also, if you’re using a keyboard layout other than US, you might want to persist the current keyboard layout. In /etc/vconsole.conf:

KEYMAP=br-abnt2

Network configuration

Set the hostname (name of your machine) by creating the /etc/hostname and adding the name of your hostname inside it.

Now, in order to prevent software unsafely resolving localhost over the network because they migh still read /etc/hosts, add the following entries to /etc/hosts:

127.0.0.1        localhost
::1              localhost
127.0.1.1        yourhostname

User configuration

Create a root password:

passwd

Create your user with administrative privileges (the -s can be omitted as bash is the default shell). In my case, my username will be gus:

useradd -m -G wheel,rfkill -s /bin/bash gus

Specify the password for the created user:

passwd gus

In order to enable the recently created user to have administrative privileges (e.g. be able to use sudo), you’ll need to uncomment the wheel line on:

EDITOR=vim visudo

If you want, you can specify the full user name with:

chfn -f "Gustavo Dantas" gus

Initramfs

In /etc/mkinitcpio.conf, add btrfs to MODULES

Still in /etc/mkinitcpio.conf, make sure the HOOKS looks like the following

HOOKS=(base udev autodetect microcode modconf kms keyboard keymap consolefont block encrypt filesystems fsck)

Regenerate initramfs:

mkinitcpio -P

Boot loader

You can use grub or systemd. I’ll use grub because it enables more customization and there are some packages that allows restoring snapshots from the grub interface as well.

pacman -S grub efibootmgr

Generate the bootloader:

grub-install --target=x86_64-efi --efi-directory=/boot --bootloader-id=GRUB

Now you need to obtain the UUID of the partition the system was installed:

blkid

Edit /etc/default/grub and at the line beginning with GRUB_CMDLINE_LINUX_DEFAULT, insert at the end with a space after quiet. Replace the content of [UUID] with the correspondent UUID of your system partition:

root=/dev/mapper/cryptroot cryptdevice=UUID=[UUID]:root 

Regenerate grub.cfg:

grub-mkconfig -o /boot/grub/grub.cfg

Now it’s time to add or configure additional software, like:

  • Enabling networking on reboot:
systemctl enable NetworkManager.service
  • Pacman cache clearner:
systemctl enable paccache.timer
  • And if you’re using SSD, enable TRIM:
systemctl enable fstrim.timer

It’s time to exit chroot, reboot the system and remove the installation medium.

You should be prompted to enter the password of the encrypted partition right before loggin in.

Snapshots

Install snapper:

sudo pacman -S snapper

When the snapshot configuration is created with snapper, it will also create a subvolume and a folder called /.snapshots, even thouth the snapshots subvolume was alreay created and mounted on /.snapshots

To fix this:

  1. Unmount snapshots subvolume
sudo umount /.snapshots
  1. Delete the /.snapshots folder
sudo rm -r /.snapshots
  1. Create snapper config

    sudo snapper -c root create-config /
    
    • Check that snapper created the subvolume
    sudo btrfs subvolume list /
    
  2. Delete the newly created subvolume and folder

sudo btrfs subvolume delete /.snapshots
  1. Create the /.snapshots folder again
sudo mkdir /.snapshots
  1. Remount it to snapshots subvolume
sudo mount -a

Now give the right read, write and execute permissions to the snapshots:

sudo chmod 750 /.snapshots

Add your user to ALLOW_USERS="yourusername" in the snapper config at /etc/snapper/configs/root. You can also change the frequency and the history listed on the snapper wiki page:

sudo vim /etc/snapper/configs/root

Enable the snapper services:

sudo systemctl enable --now snapper-timeline.timer
sudo systemctl enable --now snapper-cleanup.timer

AUR helper

An AUR helper automates the usage of the Arch User Repository (which is one of the great pros about using Arch really).

Even when I used Arch on WSL, I really liked yay, because it’s really fun to type :)

But you can also choose another one (like paru which is written in Rust), or if you’re really going in Arch Linux way, get familiar with the manual build process

Anyway, I’m installing yay. From the docs:

pacman -S --needed git base-devel && git clone https://aur.archlinux.org/yay-bin.git && cd yay-bin && makepkg -si

In order to take a snapshot after every single install with pacman so you can revert if an upgrade breaks something, we can use snap-pac-grub. But, because of the way the partitions were configured, the /boot is not being snapshotted, so in order to copy the files of /boot on every Linux kernel upgrade, rsync will be installed.

yay -S snap-pac-grub rsync

There’s also the possibility to enable booting the snapshots from grub. For that, in /etc/mkinitcpio.conf add grub-btrfs-overlayfs to the end of HOOKS. And don’t forget to regenerate your initramfs:

sudo mkinitcpio -P

Kernel snapshots

As said above, the /boot is not being snapshotted, so if an update causes instability, you’ll need to restore the older kernel image. For that:

  1. Create the folder /etc/pacman.d/hooks
sudo mkdir /etc/pacman.d/hooks
  1. In the recently created folder, create a hook that will sync /boot before a kernel upgrade
sudo vim /etc/pacman.d/hooks/0-bootbackup-preupdate.hook
[Trigger]
Operation = Upgrade
Operation = Install
Operation = Remove
Type = Path
Target = usr/lib/modules/*/vmlinuz
    
[Action]
Depends = rsync
Description = Backing up /boot before updating...
When = PreTransaction
Exec = /usr/bin/rsync -a --delete /boot /.bootbackup/preupdate
  1. Duplicate the hook to copy the new kernel after updating
sudo cp /etc/pacman.d/hooks/0-bootbackup-preupdate.hook /etc/pacman.d/hooks/95-bootbackup-postupdate.hook
[Trigger]
Operation = Upgrade
Operation = Install
Operation = Remove
Type = Path
Target = usr/lib/modules/*/vmlinuz
    
[Action]
Depends = rsync
Description = Backing up /boot after updating...
When = PostTransaction
Exec = /usr/bin/rsync -a --delete /boot /.bootbackup/postupdate

Reboot the system.

Now make an image for rollback to the system as it is in case something goes wrong in the near future:

sudo snapper -c root create --description “Clean BTRFS install with Snapper”

Conclusion

Of course, from here there are endless possibilities for the system to be configured and since I don’t have a preference yet, I’ll leave it up to your creativity.

But, if you’re really curious about what I do from here, you can check my dotfiles.

That’s it! Hope you enjoyed it. Please contact me if you have any suggestions, recommendations, tips, questions or if you just want to have philosophical conversations!

Troubleshoot

  • During the installation with pacstrap, I received some errors about someone’s signature key is unknown trust or invalid or corrupted package (PGP signature).
    • I had to refresh the keys for it to work properly (this might take some time)
pacman-key --refresh-keys

Reference