Arch Linux, Installation

This is not a comprehensive set instructions for installing Arch Linux. The official guide can be found at Installation guide. This article also does not explain the underlying concepts or mental model.

What it is a collection of notes on how I installed Arch Linux, for my own reference and to track my learning path.

Special thanks to Mischa van de Burg, who runs the amazing KubeCraft Accelerator community and teaches people about DevOps. Out of respect for Mischa's community, I will not publish certain details that are specific to his videos.

Tips

Before installing, make sure you have backed up all important data from your hard disk, as it will be erased during this installation.

Get the iso file

https://archlinux.org/download/#http-downloads

Check sums

$ gb2sum -c b2sums.txt # for linux: b2sum -c b2sums.txt

To make it work on MacOs, install coreutils

$ brew install coreutils

Check signatures

$ sq verify --signer-file release-key.pgp --signature-file archlinux-x86_64.iso.sig archlinux-x86_64.iso

Create a boot USB flash drive

Check the name of your USB flash drive

$ diskutil list # find your USB here, in my case it is /dev/disk4

Write the ISO to the USB flash drive. Be careful with the "of=" path to avoid overwriting the wrong drive

$ diskutil unmountDisk /dev/disk4
$ sudo dd if=./archlinux-x86_64.iso of=/dev/disk4 status=progress

Boot from USB

Boot the computer you want to install Arch Linux on from the USB drive. Make sure you disable Secure Boot in the BIOS settings and set up booting priority to that USB.

Choose "Arch medium" and it will start to install. Depending on a computer, it may take about a minute.

Starting from now, do not reboot the computer until you set up the boot loader. Otherwise you loose all of the installation progress.

Connect via SSH from the laptop

Now I want to connect to this computer from my laptop via SSH because it is more convenient for installation.

Check the network settings

$ systemctl start sshd.service # my ISO image already has is enabled
$ ip address # get your IP

As my computer does not have wifi, I am connecting via the cable. My network device, "enp2s0" is in status "UP". It means the computer has internet connection. If I install Arch to a computer via wifi, I will add that experience here too.

Check, that connected has been established

$ ping archlinux.org

Check the ssh

$ systemctl status sshd.service # check for Active: active (running)

Set a password for the root user. This is a temporary password for the installation needs only

$ passwd

Now you have to be able to connect to this computer via ssh from another computer

$ ssh root@192.168.1.133

To install Arch Linux follow the installation guide:
https://wiki.archlinux.org/title/Installation_guide

For Wi-Fi, authenticate to the wireless network using the iwctl utility.
For mobile broadband (WWAN) modems, connect with the mmcli utility.
Ethernet, WLAN and WWAN interfaces using DHCP should work automatically.

After connecting to the internet, the installation guide can be accessed
via the convenience script Installation_guide.

Continue installation

Check that your time is synchronized

$ timedatectl

               Local time: Sat 2025-09-06 09:21:57 UTC
           Universal time: Sat 2025-09-06 09:21:57 UTC
                 RTC time: Sat 2025-09-06 09:21:57
                Time zone: UTC (UTC, +0000)
System clock synchronized: yes
              NTP service: active
          RTC in local TZ: no

Partition

Check your current devices

$ lsblk

NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINTS
loop0    7:0    0 946.7M  1 loop /run/archiso/airootfs
sda      8:0    0 232.9G  0 disk
├─sda1   8:1    0     1G  0 part
└─sda2   8:2    0 231.9G  0 part
sdb      8:16   1  14.4G  0 disk
├─sdb1   8:17   1   1.2G  0 part
└─sdb2   8:18   1   248M  0 part

Here, "sda" is my Hard disk and "sdb" is my boot USB disk. The goal is to create correct partitions on the "sda" disk. As I already have some partitions from my previous OS, first I am going to delete them. I am going to use fdisk.

Danger zone, here is going to be formatting the main disk. If you have any data on it, you will lose it.

$ fdisk /dev/sda
$ d # run this command as many times as needed to remove all existing partitions
$ w # apply new scheme

Check that "sda" is empty

$ lsblk

NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
loop0 7:0 0 946.7M 1 loop /run/archiso/airootfs
sda 8:0 0 232.9G 0 disk
sdb 8:16 1 14.4G 0 disk
├─sdb1 8:17 1 1.2G 0 part
└─sdb2 8:18 1 248M 0 part

Disk is empty, let's create new partitions

$ fdisk /dev/sda
$ n # create a partition

First sector (2048-488397134, default 2048): # press Enter, accept the default
Last sector, +/-sectors or +/-size{K,M,G,T,P} (2048-488397134, default 488396799): +1G # type +1G, press Enter. For the boot partition the doc recommends 1G (1.9.1 Example layouts)
Created a new partition 1 of type 'Linux filesystem' and of size 1 GiB.

I need the boot loader to have the type of "EFI System"

$ t # start changing the type
$ L # show the list of possible types
$ 1 # choose the EFI system, press Enter

Create another partition, the main one

$ n

First sector (2099200-488397134, default 2099200) # press Enter, accept the default
Last sector, +/-sectors or +/-size{K,M,G,T,P} (2099200-488397134, default 488396799): +200G # add 200G, press Enter
Created a new partition 2 of type 'Linux filesystem' and of size 200 GiB.

$ t
$ L
$ 44 # choose the Linux LVM, press Enter

Check the current table

$ p

Device Start End Sectors Size Type
/dev/sda1 2048 2099199 2097152 1G EFI System
/dev/sda2 2099200 421529599 419430400 200G Linux LVM

Check disks

$ lsblk

NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
loop0 7:0 0 946.7M 1 loop /run/archiso/airootfs
sda 8:0 0 232.9G 0 disk
 ├─sda1 8:1 0 1G 0 part
 └─sda2 8:2 0 200G 0 part
sdb 8:16 1 14.4G 0 disk
 ├─sdb1 8:17 1 1.2G 0 part
 └─sdb2 8:18 1 248M 0 part

Apply the new scheme

$ w

Encrypting

I encrypted my disk using dm-crypt according to the instructions by Mischa in his community. For the license reasons, I do not publish all of the steps here, but highly recommend to check his materials, they are insane.

Formatting disks

$ mkfs.ext4 /dev/guzun/root

mke2fs 1.47.3 (8-Jul-2025)
Creating filesystem with 8388608 4k blocks and 2097152 inodes
Filesystem UUID: 8ee3a40e-723b-4bab-8aa6-fff589bc20b3
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
4096000, 7962624

Allocating group tables: done
Writing inode tables: done
Creating journal (65536 blocks): done
Writing superblocks and filesystem accounting information: done
$ mkfs.ext4 /dev/guzun/home

mke2fs 1.47.3 (8-Jul-2025)
Creating filesystem with 39321600 4k blocks and 9830400 inodes
Filesystem UUID: e5204abe-ae2a-4a7a-ab75-1a2e791d3cf8
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
4096000, 7962624, 11239424, 20480000, 23887872

Allocating group tables: done
Writing inode tables: done
Creating journal (262144 blocks): done
Writing superblocks and filesystem accounting information: done
$ mkswap /dev/guzun/swap Setting up swapspace version 1, size = 8 GiB
(8589930496 bytes) no label, UUID=15c982f1-0925-446c-a2d0-bd032ffe6783
$ mkfs.fat -F32 /dev/sda1 mkfs.fat 4.2 (2021-01-31)

Check disks

$ lsblk

NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
loop0 7:0 0 946.7M 1 loop /run/archiso/airootfs
sda 8:0 0 232.9G 0 disk
├─sda1 8:1 0 1G 0 part
└─sda2 8:2 0 200G 0 part
  └─cryptlvm 253:0 0 200G 0 crypt
    ├─guzun-swap 253:1 0 8G 0 lvm
    ├─guzun-root 253:2 0 32G 0 lvm
    └─guzun-home 253:3 0 150G 0 lvm
sdb 8:16 1 14.4G 0 disk
├─sdb1 8:17 1 1.2G 0 part
└─sdb2 8:18 1 248M 0 part

Mounting

$ mount --mkdir /dev/guzun/root /mnt
$ mount --mkdir /dev/guzun/home /mnt/home
$ mount --mkdir /dev/sda1 /mnt/boot
$ swapon /dev/guzun/swap
$ lsblk

NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
loop0 7:0 0 946.7M 1 loop /run/archiso/airootfs
sda 8:0 0 232.9G 0 disk
  ├─sda1 8:1 0 1G 0 part /mnt/boot
                       │ /mnt/boot
  └─sda2 8:2 0 200G 0 part
    └─cryptlvm 253:0 0 200G 0 crypt
      ├─guzun-swap 253:1 0 8G 0 lvm [SWAP]
      ├─guzun-root 253:2 0 32G 0 lvm /mnt
      └─guzun-home 253:3 0 150G 0 lvm /mnt/home
sdb 8:16 1 14.4G 0 disk
  ├─sdb1 8:17 1 1.2G 0 part
  └─sdb2 8:18 1 248M 0 part

Installation

$ pacstrap -K /mnt base linux linux-firmware
$ genfstab -U /mnt >> /mnt/etc/fstab

$ cat /mnt/etc/fstab

# Static information about the filesystems.
# See fstab(5) for details.
# <file system> <dir> <type> <options> <dump> <pass>
# /dev/mapper/guzun-root
UUID=8ee3a40e-723b-4bab-8aa6-fff589bc20b3 / ext4 rw,relatime 1
# /dev/mapper/guzun-root
UUID=8ee3a40e-723b-4bab-8aa6-fff589bc20b3 / ext4 rw,relatime 2
# /dev/mapper/guzun-home
UUID=e5204abe-ae2a-4a7a-ab75-1a2e791d3cf8 /home ext4 rw,relatime 2
# /dev/sda1
UUID=C58F-33B8 /boot vfat rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=ascii,shortname=mixed,utf8,errors=remount-ro
# /dev/mapper/guzun-swap
UUID=15c982f1-0925-446c-a2d0-bd032ffe6783 none swap defaults 0

Arch-chroot

$ arch-chroot /mnt

Localtime

$ ln -sf /usr/share/zoneinfo/Europe/Amsterdam /etc/localtime
$ locale-gen

Install required packages

$ pacman -Syu vim sudo which man-db man-pages texinfo amd-ucode lvm2

Networking

Disclamer. I don't know why yet, but network does not work by default after rebooting. After rebooting, come back here and set it up.

$ systemctl enable systemd-networkd.service

Created symlink '/etc/systemd/system/dbus-org.freedesktop.network1.service''/usr/lib/systemd/system/systemd-networkd.service'.
Created symlink '/etc/systemd/system/multi-user.target.wants/systemd-networkd.service''/usr/lib/systemd/system/systemd-networkd.service'.
Created symlink '/etc/systemd/system/sockets.target.wants/systemd-networkd.socket''/usr/lib/systemd/system/systemd-networkd.socket'.
Created symlink '/etc/systemd/system/sysinit.target.wants/systemd-network-generator.service''/usr/lib/systemd/system/systemd-network-generator.service'.
Created symlink '/etc/systemd/system/network-online.target.wants/systemd-networkd-wait-online.service''/usr/lib/systemd/system/systemd-networkd-wait-online.service'.

$ systemctl enable systemd-resolved.service

Created symlink '/etc/systemd/system/dbus-org.freedesktop.resolve1.service''/usr/lib/systemd/system/systemd-resolved.service'.
Created symlink '/etc/systemd/system/sysinit.target.wants/systemd-resolved.service''/usr/lib/systemd/system/systemd-resolved.service'.

Check the name of the network device

$ ip address

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host noprefixroute
valid_lft forever preferred_lft forever
2: enp2s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether a8:a1:59:2a:48:1f brd ff:ff:ff:ff:ff:ff
altname enxa8a1592a481f
inet 192.168.1.132/24 metric 100 brd 192.168.1.255 scope global dynamic enp2s0
valid_lft 70992sec preferred_lft 70992sec
inet6 fe80::aaa1:59ff:fe2a:481f/64 scope link proto kernel_ll
valid_lft forever preferred_lft forever

Create a network config

$ vim /etc/systemd/network/14-cable.network

# [Match]
# Name=enp2s0
# [Network]
# DHCP=yes

Do it after rebooting

$ ip link # find your decide name (enp2s0)
$ sudo ip link set enp2s0 up
$ ip addr show enp2s0 # you should see the ip address
$ sudo systemctl enable systemd-networkd
$ sudo systemctl start systemd-networkd
$ sudo systemctl enable systemd-resolved
$ sudo systemctl start systemd-resolved
$ sudo ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
$ sudo systemctl restart systemd-networkd

Locale

$ vim /etc/locale.conf # add the line: LANG=\_en_US.UTF-8
$ vim /etc/locale.gen # uncomment the line: en_US.UTF-8 UTF-8
$ locale-gen
$ vim /etc/mkinitcpio.conf
# Adjust
# HOOKS=(base systemd autodetect microcode modconf kms keyboard sd-vconsole block sd-encrypt lvm2 filesystems fsck)
$ vim /etc/vconsole.conf # add there FONT=latarcyrheb-sun32

Check that that font exists

$ ls /usr/share/kbd/consolefonts/ | grep latarcyrheb # shoud give some results
$ mkinitcpio -P # check that it does not have errors, warnings are ok

Boot loader

There is an issue.

The fix

bootctl --esp-path=/mnt/boot install # outside of the chroot
arch-chroot /mnt
bootctl install
$ bootctl status

System:
Not booted with EFI

Available Boot Loaders on ESP:
ESP: /boot
File: ├─/EFI/systemd/systemd-bootx64.efi (systemd-boot 257.9-1-arc>
└─/EFI/BOOT/BOOTX64.EFI (systemd-boot 257.9-1-arch)

Boot Loader Entries:
$BOOT: /boot
token: arch

Create a loader entity for Arch. The loader entry for Arch should use the correct UUID for ⁠rd.luks.name

$ vim /boot/loader/entries/arch.conf

# title Arch Linux
# linux /vmlinuz-linux
# initrd /initramfs-linux.img
# options rd.luks.name=67c3f4cb-d090-4de4-bdd1-617d7c9493af=guzun root=/dev/guzun/root rw
$ lsblk

NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
loop0 7:0 0 946.7M 1 loop
sda 8:0 0 232.9G 0 disk
  ├─sda1 8:1 0 1G 0 part /boot
  └─sda2 8:2 0 200G 0 part # this partition is encrypted
    └─cryptlvm 253:0 0 200G 0 crypt
      ├─guzun-swap 253:1 0 8G 0 lvm [SWAP]
      ├─guzun-root 253:2 0 32G 0 lvm /
      └─guzun-home 253:3 0 150G 0 lvm /home
sdb 8:16 1 14.4G 0 disk
  ├─sdb1 8:17 1 1.2G 0 part
  └─sdb2 8:18 1 248M 0 part
$ blkid

/dev/sda2: UUID="67c3f4cb-d090-4de4-bdd1-617d7c9493af" TYPE="crypto_LUKS" PARTUUID="48cacec3-4344-444e-a3bb-bf84bf78758b"
/dev/sda1: UUID="C58F-33B8" BLOCK_SIZE="512" TYPE="vfat" PARTUUID="a3ac44c7-e3d3-4025-bafc-1c53c6225608"
/dev/mapper/guzun-swap: UUID="15c982f1-0925-446c-a2d0-bd032ffe6783" TYPE="swap"
/dev/sdb2: LABEL_FATBOOT="ARCHISO_EFI" LABEL="ARCHISO_EFI" UUID="68B5-CBAE" BLOCK_SIZE="512" TYPE="vfat" PARTUUID="2d9d5c0b-02"
/dev/sdb1: BLOCK_SIZE="2048" UUID="2025-09-01-16-37-02-00" LABEL="ARCH_202509" TYPE="iso9660" PARTUUID="2d9d5c0b-01"
/dev/mapper/guzun-root: UUID="8ee3a40e-723b-4bab-8aa6-fff589bc20b3" BLOCK_SIZE="4096" TYPE="ext4"
/dev/loop0: BLOCK_SIZE="1048576" TYPE="squashfs"
/dev/mapper/cryptlvm: UUID="Ez0FVZ-jMhV-eP7Y-mqrL-MPKZ-kOKu-rJMAy7" TYPE="LVM2_member"
/dev/mapper/guzun-home: UUID="e5204abe-ae2a-4a7a-ab75-1a2e791d3cf8" BLOCK_SIZE="4096" TYPE="ext4"

Create a user

$ useradd -m vitaly
$ usermod -aG wheel vitaly
$ groups vitaly # vitaly : vitaly wheel

Allow users in the 'wheel' group to run commands as administrator (sudo)

$ visudo # uncomment the line: %wheel ALL...

Create passwords:

$ passwd # password for the admin
$ passwd vitaly # password for the user

All done! You can now reboot your computer and remove the USB drive. Arch Linux should boot up. If the system does not boot, check the BIOS for the boot priority. It should be your hard disk.

$ reboot