Base system Installation

How to install an Arch Linux base system




Download the ISO and create a bootable USB Device

Option Download
Arch Linux https://archlinux.org/download/
balenaEtcher https://www.balena.io/etcher/
Rufus https://rufus.ie/
Note

If you experience glitches on booting the installation medium with a nVidia graphics card and do not see the command line
edit USBDEVICE/loader/entries/01-archiso-x86_64-linux.conf on your installation medium device
and add nomodeset as boot parameter

Tip

Press E during systemd-boot selection and pass nomodeset


Boot the installation medium and ensure that you’re using EFI

ls /sys/firmware/efi

Ensure you have internet connectivity

Plug in a ethernet cable or if you use Wi-Fi

wifi-menu

Login to your Network and note your IPADRESS

ip a s

Check the Network Connection

ping -c 3 1.1.1.1

Set USB installation media password for the root user

passwd

Enable SSH on the installation medium

systemctl start sshd
systemctl status sshd
Tip

You may continue the installation through SSH from another Computer

ssh root@IPADRESS

Check the avaible devices

lsblk -f

Choose the device you want to install Arch Linux


Partition disk

cfdisk /dev/nvme1n1

Select GPT label type, then select Free Space then hit on New from bottom menu.
Type the partition size in GiB (1G) and press enter key, select Type from bottom menu and choose EFI System partition type.
For /(root) partition use the following configuration: New -> Size: 100G-> Type Linux root.
For /home partition use the following configuration: New -> Size: rest of free space -> Type Linux home.

Option Size Type
/boot 1G EFI System partition
/(root) 100G Linux root
/home Rest Linux home
Warning

All previous files on the device will be erased

After you review the partition table select Write, answer with yes in order to apply disk changes and then, type quit to exit cfdisk utility.

Tip

You can also review the partition table summary by running fdisk command.

fdisk -l

Format partitions

mkfs.fat -F32 /dev/nvme1n1p1
mkfs.xfs /dev/nvme1n1p2
mkfs.xfs /dev/nvme1n1p3

Check partitions

lsblk -f

Mount partitions

Mount root partition

mount /dev/nvme1n1p2 /mnt

Mount boot partition

mkdir -pv /mnt/boot
chmod 0700 /mnt/boot
mount -o fmask=0137,dmask=0027 /dev/nvme1n1p1 /mnt/boot

Mount home partition

mkdir -pv /mnt/home
mount /dev/nvme1n1p3 /mnt/home

Install arch base running package installs against mount

pacstrap -i /mnt linux linux-firmware base base-devel amd-ucode sudo zsh zsh-autosuggestions zsh-completions zsh-syntax-highlighting
Tip

Install intel-ucode for Intel processors


Generate a Filesystem Table (fstab)

genfstab -U -p /mnt >> /mnt/etc/fstab
Note
# Static information about the filesystems.
# See fstab(5) for details.

# <device> <dir> <type> <options> <dump> <fsck>
# If the root file system is btrfs or XFS, the fsck order should be set to 0 instead of 1.

# /dev/nvme1n1p2
UUID=1314508c-df47-4972-822c-7e60c9cd12eb / xfs defaults 0 0
# /dev/nvme1n1p1
UUID=1DE1-20E9 /boot vfat rw,relatime,fmask=0137,dmask=0027,codepage=437,iocharset=ascii,shortname=mixed,utf8,errors=remount-ro	0 2
# /dev/nvme1n1p3
UUID=3650e797-e902-4c6a-a704-6aa3b3b448a9 /home xfs defaults 0 0


# /dev/sda1
UUID=07f20613-d710-4141-831d-60ca79f7dbd2 /mnt/sda1 ext4 defaults,noatime,noauto,x-systemd.automount 0 0
# /dev/sdb1
UUID=ca5f78a9-71db-408f-9148-b3add8dd7c80 /mnt/sdb1 ext4 defaults,noatime,noauto,x-systemd.automount 0 0


# ntfs3
# /dev/nvme0n1p2
# UUID=CCB22606B225F59C /mnt/nvme0n1p2 ntfs3 defaults,discard,noatime,noauto,x-systemd.automount 0 0
# /dev/nvme0n1p3
# UUID=0125876E5D886075 /mnt/nvme0n1p3 ntfs3 defaults,discard,noatime,noauto,x-systemd.automount 0 0
# /dev/nvme2n1p1
# UUID=73C99ED2175A3468 /mnt/nvme2n1p1 ntfs3 defaults,discard,noatime,noauto,x-systemd.automount 0 0
# /dev/nvme3n1p1
# UUID=0436AA0013BB9B40 /mnt/nvme3n1p1 ntfs3 defaults,discard,noatime,noauto,x-systemd.automount 0 0

# /dev/sdc1
# UUID=43B0754E6391E844 /mnt/sdc1 ntfs3 defaults,noatime,noauto,x-systemd.automount 0 0
# /dev/sdd1
# UUID=72B601494AED575D /mnt/sdd1 ntfs3 defaults,noatime,noauto,x-systemd.automount 0 0

# nfs
10.0.1.11:/srv/nfs/music /mnt/nfs/music nfs noauto,x-systemd.automount,x-systemd.device-timeout=10,timeo=14,x-systemd.idle-timeout=1min 0 0

# hugepages
# hugetlbfs /dev/hugepages hugetlbfs mode=01770,gid=kvm 0 0

Chroot to install directory

arch-chroot /mnt

Set the machine hostname

echo "archlinux" >> /etc/hostname

Set timezone

Remove old localtime

rm /etc/localtime
ln -s /usr/share/zoneinfo/Europe/Berlin /etc/localtime

Set hardware clock to UTC

hwclock --systohc --utc

Synchronize the system clock

/etc/systemd/timesyncd.conf
[Time]
NTP=ptbtime1.ptb.de ptbtime2.ptb.de ptbtime3.ptb.de
FallbackNTP=0.arch.pool.ntp.org 1.arch.pool.ntp.org 2.arch.pool.ntp.org 3.arch.pool.ntp.org
RootDistanceMaxSec=5
PollIntervalMinSec=32
PollIntervalMaxSec=2048
ConnectionRetrySec=30
SaveIntervalSec=60
systemctl enable systemd-timesyncd
timedatectl show-timesync --all

Edit locale

/etc/locale.gen

uncomment en_US.UTF-8 UTF8

locale-gen
echo LANG=en_US.UTF-8 >> /etc/locale.conf

Customize pacman & enable multilib and Arch AUR community repositories

/etc/pacman.conf

uncomment [multilib]; Include = /etc/pacman.d/mirrorlist
uncomment Color
add ILoveCandy


Installing the systemd bootloader

bootctl install
bootctl --path=/boot install
Note

Whenever there is a new version of systemd-boot, the boot manager must be updated by the user.

bootctl update
Tip

Create an automatic bootctl update hook for pacman

/etc/pacman.d/hooks/100-systemd-boot.hook
[Trigger]
Type = Package
Operation = Upgrade
Target = systemd

[Action]
Description = Updating systemd-boot
When = PostTransaction
Exec = /usr/bin/bootctl update

Setup the systemd bootloader

/boot/loader/loader.conf
default arch.conf
timeout 0
console-mode max
editor no
auto-entries 0
auto-firmware 1

Add an entry for Arch Linux

/boot/loader/entries/arch.conf
title Arch Linux
linux /vmlinuz-linux
initrd /amd-ucode.img
initrd /initramfs-linux.img
options root=UUID=1314508c-df47-4972-822c-7e60c9cd12eb rw quiet
Info

If you are dual booting Windows you can add an manual entry for it

/boot/loader/entries/windows.conf
title Microsoft Windows
efi /EFI/Microsoft/Boot/bootmgfw.efi

Set root password

passwd

Change root shell

usermod -s /usr/bin/zsh root

Create non-privileged user and add him to the wheel group

Warning

Create a normal user for daily use. Do not use the root user for daily use.

useradd -m -G wheel -s /usr/bin/zsh USER

Set user password

passwd USER

Edit sudoers

/etc/sudoers
# Enable insults
Defaults insults

# Ask for the root password instead of the user password
Defaults targetpw

# Infinite password timeout
Defaults passwd_timeout=0

# # Password timeout
# Defaults passwd_timeout=1800

uncomment root ALL=(ALL) ALL
uncomment %wheel ALL=(ALL:ALL) ALL

Warning

Set Sudoers default file permissions The owner and group for the sudoers file must both be 0.
The file permissions must be set to 0440.
These permissions are set by default, but if you accidentally change them,
they should be changed back immediately or sudo will fail.

chown -c root:root /etc/sudoers
chmod -c 0440 /etc/sudoers

Networking

Disable systemd-networkd and istall Network Manager

rm /etc/systemd/network/*
pacman -Syu networkmanager
systemctl disable systemd-resolved
systemctl disable systemd-networkd
systemctl enable NetworkManager

Disable IPv6

/etc/sysctl.d/40-ipv6.conf
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1

Configure Connection

nmcli connection edit Wired\ connection\ 1
set connection.id enp1s0
set ipv6.method disabled
save persistent
quit

Local hostname resolution

/etc/hosts
# Static table lookup for hostnames.
# See hosts(5) for details.
127.0.0.1        localhost
::1              localhost

Networking through wired adapter using DHCP

/etc/systemd/network/20-wired.network
[Match]
Name=en*

[Network]
DHCP=yes

Wireless Network using DHCP

/etc/systemd/network/25-wireless.network
[Match]
Name=wl*

[Network]
DHCP=yes

[DHCPv4]
RouteMetric=20

Wireless network configuration


Enable systemd network

systemctl enable systemd-resolved -f
systemctl enable systemd-networkd -f
Tip

NetworkManager prefers known wireless networks and has the ability to switch to the most reliable network.

Warning

You must ensure that only one service that wants to configure the network is running.
Multiple networking services will conflict.
You can find a list of the currently running services with systemctl --type=service and then stop them.


Exit chroot, unmount and reboot

exit
umount -R /mnt
reboot now

Autoupdate mirrorlist

Install reflector

pacman -Syu reflector

Edit reflector configuration

/etc/xdg/reflector/reflector.conf
# Recommended Options

# Set the output path where the mirrorlist will be saved (--save).
--save /etc/pacman.d/mirrorlist

# Select the transfer protocol (--protocol).
--protocol https

# Select the country (--country).
# Consult the list of available countries with "reflector --list-countries" and
# select the countries nearest to you or the ones that you trust. For example:
--country Switzerland,Germany

# Use only the  most recently synchronized mirrors (--latest).
--latest 10

# Sort the mirrors by synchronization time (--sort).
--sort rate

Enable reflector timer and start reflector service

systemctl start reflector.service
systemctl enable reflector.timer

Discard unused packages weekly to prevent the directory to grow indefinitely in size

systemctl enable paccache.timer

Update system

pacman -Syu

Install base programs

pacman -Syu xfsprogs pacman-contrib openssh curl wget rsync git htop tldr fd ack ncdu duf man-db tree logrotate net-tools btop pwgen nfs-utils neofetch

Install additional kernel

pacman -Syu linux-lts linux-zen

Remove fallback from presets

/etc/mkinitcpio.d/linux-zen.preset
# mkinitcpio preset file for the 'linux-zen' package

#ALL_config="/etc/mkinitcpio.conf"
ALL_kver="/boot/vmlinuz-linux-zen"
ALL_microcode=(/boot/*-ucode.img)

PRESETS=('default')

#default_config="/etc/mkinitcpio.conf"
default_image="/boot/initramfs-linux-zen.img"
#default_uki="/efi/EFI/Linux/arch-linux-zen.efi"
#default_options="--splash /usr/share/systemd/bootctl/splash-arch.bmp"

#fallback_config="/etc/mkinitcpio.conf"
fallback_image="/boot/initramfs-linux-zen-fallback.img"
#fallback_uki="/efi/EFI/Linux/arch-linux-zen-fallback.efi"
fallback_options="-S autodetect"

Install fonts

pacman -Syu ttf-ubuntu-font-family ttf-jetbrains-mono noto-fonts-emoji

Install AMDGPU driver

pacman -Syu lib32-mesa mesa xf86-video-amdgpu lib32-vulkan-radeon vulkan-radeon lib32-libva-mesa-driver libva-mesa-driver lib32-mesa-vdpau mesa-vdpau

Setup AUR

Enable compiler using all CPU threads

/etc/makepkg.conf

uncomment and edit MAKEFLAGS="-j $(nproc)"
uncomment and edit COMPRESSXZ=(xz -c -T $(nproc) -z -)

Download AUR Helper

git clone https://aur.archlinux.org/yay.git
cd yay
makepkg -si

Modify intiramfs

/etc/mkinitcpio.conf
MODULES=(amdgpu)
...
HOOKS=(base udev autodetect modconf kms keyboard keymap block filesystems fsck)

Tip

Install optional firmware for the default linux kernel to get rid of the annoying
‘WARNING: Possibly missing firmware for module:’ message

yay -Syu mkinitcpio-firmware

Note

Despite XFS supporting async discard since kernel 4.7, xfs still recommends “that you use the fstrim application to discard unused blocks rather than the discard mount option because the performance impact of this option is quite severe.”

Enable weekly TRIM service for SSD devices

systemctl enable fstrim.timer

Enable Logrotate

systemctl enable logrotate.timer
/etc/logrotate.conf
# uncomment this if you want your log files compressed
compress
compresscmd /usr/bin/zstd
compressext .zst
compressoptions -T0 --long
uncompresscmd /usr/bin/unzstd

Remove memory limit

mkdir -pv /etc/security/limits.d
/etc/security/limits.d/10-gcr.conf
*               hard    memlock         unlimited
*               soft    memlock         unlimited
*               hard    nofile          1048576

Run ulimit -l to check limits


Set max user watches

echo fs.inotify.max_user_watches=524288 | tee /etc/sysctl.d/50-max_user_watches.conf && sysctl --system

Run cat /proc/sys/fs/inotify/max_user_watches to check it’s working


Enable Nano syntax highlighting

/etc/nanorc

uncomment include "/usr/share/nano/*.nanorc"


Disabling automatic core dumps

/etc/sysctl.d/50-coredump.conf
kernel.core_pattern=/dev/null

Reducing shutdown timeout for “a stop job is running”

/etc/systemd/system.conf

uncomment DefaultTimeoutStartSec=30s
uncomment DefaultTimeoutStopSec=30s


Add additional tty virtual consoles (CTRL+ALT+F1 - CTRL+ALT+F11)

/etc/systemd/logind.conf
NAutoVTs=11

Forward journald to /dev/tty12 (CTRL+ALT+F12)

Create a drop-in directory

mkdir -pv /etc/systemd/journald.conf.d

create a config file in it

/etc/systemd/journald.conf.d/fw-tty12.conf
[Journal]
ForwardToConsole=yes
TTYPath=/dev/tty12
MaxLevelConsole=info

Change persistent journal size limit

Create a drop-in directory

mkdir -pv /etc/systemd/journald.conf.d
/etc/systemd/journald.conf.d/00-journal-size.conf
[Journal]
SystemMaxUse=50M

Swap

Revome swap file

swapon --show
swapoff /swapfile
/etc/fstab

remove /swapfile swap swap defaults 0 0

rm /swapfile

Install Zram-generator package

pacman -Syu zram-generator

Configure Zram

/etc/systemd/zram-generator.conf
# This config file enables a /dev/zram0 device with the default settings:
# — size — same as available RAM or 8GB, whichever is less
# — compression — most likely lzo-rle
#
# To disable, uninstall zram-generator-defaults or create empty
# /etc/systemd/zram-generator.conf file.
[zram0]
zram-size = min(ram, 8192)

Enable service

systemctl enable systemd-zram-setup@

Create a swap file

dd if=/dev/zero of=/swapfile bs=1M count=8192 status=progress
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile

Edit the fstab configuration to add an entry for the swap file

/etc/fstab

/swapfile swap swap defaults 0 0

Check the current swappiness value

sysctl vm.swappiness

To set the swappiness value permanently, edit a sysctl configuration file

/etc/sysctl.d/99-swappiness.conf

vm.swappiness=10


Hibernation into swap file

Identify swap device

findmnt -no UUID -T /swapfile

Identify swap file offset

filefrag -v /swapfile | awk '$1=="0:" {print substr($4, 1, length($4)-2)}'

Add the values to the systemd bootloader options

resume=UUID=eb22c14f-a1f2-4843-ae88-c8fee6113d9d resume_offset=3762176