Arch Linux setup
With LVM on LUKS, systemd-boot bootloader, hibernation, applying user personal configuration files and preferences.
Setup process
-
Download the Arch Linux installer image.
-
Write the installation image to the installation media.
- To write the image from a *nix system:
< path/to/archlinux-version-x86_64.iso > /dev/sdx
- To write the image from Microsoft Windows, use Rufus.
- Alternatively, copy the downloaded image to a Ventoy prepared device.
- To write the image from a *nix system:
-
Disable "Secure Boot" in the BIOS of the installation target computer.
-
Boot installation target computer into Arch Linux installation media environment.
-
Verify EFI boot mode by listing efivars directory.
ls /sys/firmware/efi/efivars
-
To continue the installation remotely from another computer:
- Set the installation media root user password.
passwd
- Enable and start SSH server.
systemctl enable --now sshd
- Determine installation target computer IP address.
ip a
- From another device SSH into installation target computer to continue the setup.
ssh root@192.168.1.99
- Set the installation media root user password.
-
Wipe the installation target disk. This document assumes installation target disk is
/dev/nvme0n1
(uselsblk
to list block devices).cryptsetup open --type plain -d /dev/urandom /dev/nvme0n1 to_be_wiped dd if=/dev/zero of=/dev/mapper/to_be_wiped bs=1M status=progress 2> /dev/null cryptsetup close to_be_wiped
-
Create the top level physical partitions. Choose the option
GPT partitioning
.cfdisk /dev/nvme0n1
/dev/ mapping Size Type /dev/nvme0n1p1 512M
EFI System /dev/nvme0n1p2 rest of the drive Linux filesystem -
Format the LUKS container partition. Must provide the password.
cryptsetup luksFormat /dev/nvme0n1p2
-
Open the LUKS container.
cryptsetup luksOpen /dev/nvme0n1p2 nvme0n1_luks0
-
Create physical volume in LUKS container.
pvcreate /dev/mapper/nvme0n1_luks0
-
Create a logical volume group and add the physical volume of the LUKS container to it.
vgcreate nvme0n1_luks0_volgrp0 /dev/mapper/nvme0n1_luks0
-
Create the logical partitions in the volume group.
lvcreate -L 128G nvme0n1_luks0_volgrp0 -n root lvcreate -L 20G nvme0n1_luks0_volgrp0 -n swap lvcreate -l 100%FREE nvme0n1_luks0_volgrp0 -n home
To determine the swap partition size:
- RAM <=1 GB – at least the size of RAM, at most double the size of RAM.
- RAM >1 GB – at least equal to the square root of the RAM size and at most double the size of RAM.
- With hibernation – equal to size of RAM + the square root of the RAM size.
-
Reduce /home partition by 256MiB for e2scrub use.
lvreduce -L -256M nvme0n1_luks0_volgrp0/home
-
Format the partitions of each logical volume.
mkfs.ext4 /dev/nvme0n1_luks0_volgrp0/root mkfs.ext4 /dev/nvme0n1_luks0_volgrp0/home mkswap /dev/nvme0n1_luks0_volgrp0/swap
-
Format the /boot partition.
mkfs.vfat -F32 /dev/nvme0n1p1
-
Create mount points and mount the system partitions.
mkdir /mnt mount /dev/mapper/nvme0n1_luks0_volgrp0-root /mnt mkdir /mnt/{boot,home} mount /dev/mapper/nvme0n1_luks0_volgrp0-home /mnt/home mount /dev/nvme0n1p1 /mnt/boot
-
Initialize /swap partition.
swapon /dev/mapper/nvme0n1_luks0_volgrp0-swap
-
Update Arch official package repository mirrors.
reflector --country Latvia,Lithuania,Estonia,Finland,Sweden,Poland --protocol https --latest 10 --save /etc/pacman.d/mirrorlist
-
Install base packages.
pacstrap /mnt base linux linux-firmware networkmanager openssh sudo neovim git terminus-font lvm2
-
Generate fstab.
genfstab -U /mnt >> /mnt/etc/fstab
-
Change root path of the system.
arch-chroot /mnt
-
Install root user Neovim configuration.
mkdir -p /root/.config && cd /root/.config git clone https://github.com/andis-sprinkis/nvim-user-config nvim cd nvim && git checkout minimal-config
-
Add boot-loader directories.
mkdir -p /boot/loader/entries
-
Get the LUKS container partition UUID.
blkid --match-tag UUID -o value /dev/nvme0n1p2
-
Add boot-loader entry. Add file
/boot/loader/entries/arch.conf
:title Arch Linux linux /vmlinuz-linux initrd /initramfs-linux.img options cryptdevice=UUID=<LUKS container partition UUID>:nvme0n1_luks0 root=/dev/nvme0n1_luks0_volgrp0/root resume=/dev/nvme0n1_luks0_volgrp0/swap module_blacklist=pcspkr,snd_pcsp
Set TTY default screen rotation by specifying the
fbcon=rotate:X
boot options value.For a counter-clockwise rotation set:
options ... fbcon=rotate:1
-
Configure boot-loader. Add file
/boot/loader/loader.conf
:#timeout 0 #console-mode keep
-
Update
/etc/mkinitcpio.conf
variableHOOKS
, addingencrypt lvm2 resume
:HOOKS=(base udev autodetect modconf kms keyboard keymap consolefont block filesystems fsck encrypt lvm2 resume)
-
Regenerate initfram file.
mkinitcpio -P
-
Install systemd-boot bootloader.
bootctl --path=/boot install
-
Add pacman update hook for systemd-boot bootloader:
-
mkdir /etc/pacman.d/hooks
-
Add file
/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
-
-
Enable NetworkManager service.
systemctl enable NetworkManager
-
Set hardware clock.
hwclock --systohc
-
Set system locale.
- Add to file
/etc/locale.gen
:en_US.UTF-8 UTF-8 lv_LV.UTF-8 UTF-8
-
locale-gen
- Add file
/etc/locale.conf
LANG=en_US.UTF-8 LC_ADDRESS=lv_LV.UTF-8 LC_COLLATE=lv_LV.UTF-8 LC_CTYPE=lv_LV.UTF-8 LC_MEASUREMENT=lv_LV.UTF-8 LC_MONETARY=lv_LV.UTF-8 LC_NUMERIC=lv_LV.UTF-8 LC_PAPER=lv_LV.UTF-8 LC_TELEPHONE=lv_LV.UTF-8 LC_TIME=lv_LV.UTF-8
- Add to file
-
Set the console font and keymap. Add to file
/etc/vconsole.conf
:FONT=ter-v24b KEYMAP=lv
-
Set hostname.
echo "arch-pc-00" > /etc/hostname
-
Set root user password.
passwd root
-
Create a regular user.
useradd -m user-00 usermod -G wheel -a user-00 passwd user-00
-
Set sudo-ers.
-
EDITOR=nvim visudo
- Add or uncomment:
%wheel ALL=(ALL:ALL) ALL
-
-
Create user mount directories.
dirs=$(eval "echo /mnt/nvme{1..5} /mnt/sata{1..5} /mnt/usb{1..5} /mnt/pc{1..5} /mnt/nas{1..5} /mnt/vm{1..5} /mnt/mobile{1..5}") mkdir -p $dirs chown user-00:user-00 $dirs
-
Exit from /mnt root shell and reboot, then log in as the regular user.
exit reboot
-
Set console typematic delay and rate (keyboard input speed).
-
Add file
/etc/systemd/system/console-kbdrate.service
:[Unit] Description=Console typematic delay and rate (kbdrate). [Service] Type=oneshot RemainAfterExit=yes StandardInput=tty StandardOutput=tty ExecStart=/usr/bin/kbdrate --silent --delay 165 --rate 55 [Install] WantedBy=multi-user.target
-
systemctl enable --now console-kbdrate.service
-
-
Enable Network Time Protocol.
sudo timedatectl set-ntp on
-
Set the time zone.
sudo timedatectl set-timezone Europe/Riga
-
Clone the repository containing the user package lists.
cd $HOME git clone https://github.com/andis-sprinkis/linux-install cd linux-install
-
Install the Arch official package repository packages.
sudo pacman -S --needed $(echo $(< ./pkg_pacman))
-
If installation target computer is a VirtualBox guest, install and enable the VirtualBox guest utilities.
sudo pacman -S virtualbox-guest-utils sudo systemctl enable --now vboxservice.service
-
Install AUR helper.
temp_path=$(mktemp -d) git clone https://aur.archlinux.org/yay.git $temp_path cd $temp_path makepkg -si cd $HOME/linux-install
-
Install AUR packages.
yay -S --needed $(echo $(< ./pkg_aur))
-
Install AppImage packages.
for p in $(echo $(< ./pkg_appimage)); do curl --location --output-dir "$HOME/.local/opt/appimage" --remote-name "$p" done chmod +x $HOME/.local/opt/appimage/*
-
Install user general configuration.
git_url_cfg=https://github.com/andis-sprinkis/nix-user-config dir_cfg_git=$HOME/.dotfiles_git temp_path=$(mktemp -d) git clone --separate-git-dir=$dir_cfg_git $git_url_cfg $temp_path rsync --recursive --verbose --exclude '.git' $temp_path/ $HOME git --git-dir=$dir_cfg_git --work-tree=$HOME config --local status.showUntrackedFiles no git --git-dir=$dir_cfg_git --work-tree=$HOME submodule update --init
-
Install user Neovim configuration.
cd $HOME/.config git clone https://github.com/andis-sprinkis/nvim-user-config nvim
-
Create user download directries.
mkdir -p $HOME/dl/{_chrm,_eph,_ff,_jd2,_mnt,_qbt,_scdl,_ytdlp}
-
Switch shell to ZSH for both root and the regular user and execute ZSH.
sudo chsh -s /usr/bin/zsh root sudo chsh -s /usr/bin/zsh user-00 exec zsh
-
Install npm packages.
volta install $(echo $(< ./pkg_npm))
-
Install PyPi packages.
for p in $(echo $(< ./pkg_pypi)); do pipx install $p; done
-
Enable the audio system.
systemctl --user enable --now pipewire.socket pipewire-pulse.socket wireplumber.service
-
Enable the PC/SD Smart Card Daemon service.
sudo systemctl enable pcscd.service
-
Enable non-root users to be able to use
allow_other
mount option with FUSE. In file/etc/fuse.conf
add or uncomment lineuser_allow_other
-
Detect the hardware sensors.
sudo sensors-detect
-
To customize functions of the device power buttons:
- Update file
/etc/systemd/logind.conf
.sudo nvim /etc/systemd/logind.conf
- Restart the systemd-logind.service.
sudo systemctl restart systemd-logind.service
- Update file
-
Log out and log in again.
exit
Encryption, automatic unlocking and mounting of an another drive on the system
LVM on LUKS.
- Wipe the target disk. This document assumes the target disk is
/dev/nvme1n1
(uselsblk
to list block devices).sudo su cryptsetup open --type plain -d /dev/urandom /dev/nvme1n1 to_be_wiped dd if=/dev/zero of=/dev/mapper/to_be_wiped bs=1M status=progress 2> /dev/null cryptsetup close to_be_wiped
- Create the top level physical partition. Choose the option
GPT partitioning
and set the entire drive asLinux filesystem
.cfdisk /dev/nvme1n1
- Generate the keyfile.
dd bs=512 count=4 if=/dev/random of=/nvme1.key iflag=fullblock
- Set keyfile access permissions.
chmod a=,u=rw /nvme1.key
- Format the LUKS container partition. Must provide the password.
cryptsetup luksFormat /dev/nvme1n1p1
- Associate the keyfile with the LUKS container partition.
cryptsetup luksAddKey /dev/nvme1n1p1 /nvme1.key
- Open the LUKS container.
cryptsetup luksOpen /dev/nvme1n1p1 nvme1n1_luks0 --key-file /nvme1.key
- Create the physical volume in LUKS container.
pvcreate /dev/mapper/nvme1n1_luks0
- Create a logical volume group and add the physical volume of the LUKS container to it.
vgcreate nvme1n1_luks0_volgrp0 /dev/mapper/nvme1n1_luks0
- Create the logical partition in the volume group.
lvcreate -l 100%FREE nvme1n1_luks0_volgrp0 -n data
- Reduce the /data logical partition by 256MiB for e2scrub use.
lvreduce -L -256M nvme1n1_luks0_volgrp0/data
- Format the partition of the logical volume.
mkfs.ext4 /dev/nvme1n1_luks0_volgrp0/data
- Get the LUKS container partition UUID.
blkid --match-tag UUID -o value /dev/nvme1n1p1
- Add the LUKS container partition entry to file
/etc/crypttab
:nvme1 UUID=<LUKS container partition UUID> /nvme1.key
- Get the logical volume partition UUID.
blkid --match-tag UUID -o value /dev/mapper/nvme1n1_luks0_volgrp0-data
- Add the logical volume partition entry to file
/etc/fstab
:# /dev/mapper/nvme1n1_luks0_volgrp0-data UUID=<Logical volume partition UUID> /mnt/nvme1 ext4 rw,relatime 0 0
- Re-mount
/etc/fstab
file specified devices.mount -a systemctl daemon-reload
- Change the mounted file system ownership to the regular user.
chown -R user-00:user-00 /mnt/nvme1
- Reboot.
systemctl reboot
Connecting to Wi-Fi
- Installation media environment:
iwctl station list iwctl station $station scan iwctl station $station get-networks iwctl station $station connect $network_name
- The installed OS environment:
- Interactively:
nmtui
- Non-interactively:
nmcli device wifi connect $ssid password $password
- Interactively:
Related resources
xorg.conf
,xrandr
manpages- AMDGPU - ArchWiki
- Backlight - ArchWiki
- Intel graphics - ArchWiki
- Intel graphics - LinuxReviews
- NVIDIA - ArchWiki
- Network UPS Tools - ArchWiki
- Network UPS Tools - Hardware compatibility list
- Persistent block device naming - ArchWiki
- Smartcards - ArchWiki
- The Framebuffer Console — The Linux Kernel documentation
- Xorg - ArchWiki