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
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