Arch Linux ‐‐ Install Notes - arluke/homelab GitHub Wiki
Intro
This is more for my own personal reference but if it helps someone else then all the better. I am far from an expert on this and this is just me compiling the things I've found in solving my own issues. Very much a work in progress but should give you a functioning system.
Guide is functionalish as of February 2025 on linux-lts, kernel 6.13.4-arch1-1.
Prep
Wipe drives
Root filesystem is assumed to be on /dev/nvme0n1
. md raid5 for /home is assumed to be on /dev/nvme1n1, /dev/nvme2n1, /dev/nvme3n1
. Adjust accordingly or you're gonna have a bad time.
for i in {0..3}; do \
wipefs -a /dev/nvme${i}n1;
sgdisk --zap-all /dev/nvme${i}n1;
sgdisk -o /dev/nvme${i}n1;
done;
Partition Disks
sgdisk -n1:4096:+1GiB -t1:ef00 /dev/nvme0n1;
sgdisk -n2:0:+896GiB -t2:8309 /dev/nvme0n1
Encryption
cryptsetup -v luksFormat /dev/nvme0n1p2;
cryptsetup open /dev/nvme0n1p2 root
Format
mkfs.btrfs /dev/mapper/root;
mkfs.fat -F32 /dev/nvme0n1p1
Mounting / Subvols
Initial Mount and Top-Level Subvol creation
mount -o defaults,discard /dev/mapper/root /mnt;
btrfs subvol create /mnt/@;
umount /mnt
Remount rootfs with subvol=@
flag. Create remaining subvols and mount /efi
mount -o defaults,discard,subvol=@ /dev/mapper/root /mnt;
mkdir -p /mnt/var/cache/pacman;
btrfs subvol create /mnt/.snapshots /mnt/var/log /mnt/var/cache/pacman/pkg;
mount --mkdir -o uid=0,gid=0,fmask=0077,dmask=0077,discard /dev/nvme0n1p1 /mnt/efi;
Allocate and Activate swapfile
btrfs filesystem mkswapfile --size 32G /mnt/.swapfile;
swapon /mnt/.swapfile
Pacstrap the base system and chroot into the new environment.
pacstrap -K /mnt base linux linux-headers linux-firmware amd-ucode efibootmgr gdisk btrfs-progs mdadm sudo neovim systemd-ukify sbsigntools sbctl efitools networkmanager openssh;
genfstab -U /mnt >> /mnt/etc/fstab;
printf '\nEDITOR=nvim' >> /mnt/etc/bash.bashrc;
arch-chroot /mnt
[!IMPORTANT] If you are on an Intel-based architecture, replace
amd-ucode
withintel-ucode
Do not forget the
-U
flag forgenfstab
. Filesystem labels can change between reboots (especially PCIe flash) resulting in a failure to boot. This will create the/etc/fstab
file in your new environment using the partition UUID instead of labels.
Build /home
sgdisk -n1:4096:+1792GiB -t1:fd00 /dev/nvme1n1;
sgdisk -n1:4096:+1792GiB -t1:fd00 /dev/nvme2n1;
sgdisk -n1:4096:+1792GiB -t1:fd00 /dev/nvme3n1;
mdadm --create --verbose /dev/md/data --level=5 --raid-devices=3 \
/dev/nvme1n1p1 /dev/nvme2n1p1 /dev/nvme3n1p1
cryptsetup -v luksFormat /dev/md/data;
cryptsetup open /dev/md/data data;
mkfs.btrfs /dev/mapper/data
mount /dev/mapper/data /data
btrfs subvol create /data/@home
umount /data
mount --mkdir -o defaults,discard,subvol=@home /dev/mapper/data /home
openssl genpkey -algorithm RSA -out /etc/cryptsetup-keys.d/data.pem
echo "data UUID=${uuid} /etc/cryptsetup-keys.d/data.pem luks,discard,tries=3" > /etc/crypttab
echo "UUID=${uuid} /home btrfs rw,relatime,ssd,discard,space_cache=v2,subvol=/@home 0 0 >> /etc/fstab
Basic System Configuration
Set localtime and generate locales
Select the appropriate timezone for your system
ln -sf /usr/share/zoneinfo/America/Phoenix /etc/localtime;
hwclock --systohc
nvim /etc/locale.gen;
locale-gen;
echo LANG=en_US.UTF-8 >> /etc/locale.conf
echo KEYMAP=us >> /etc/vconsole.conf;
echo ${HOSTNAME} >> /etc/hostname;
nvim /etc/hosts
SET:
127.0.0.1 localhost
::1 localhost
127.0.0.1 HOSTNAME.LOCALDOMAIN HOSTNAME
sudo user and config sudo
groupadd --gid 5001 ssh-users;
groupadd --gid 6000 arluke;
useradd --uid 6000 --gid 6000 --groups arluke,ssh-users,wheel --shell /bin/bash --home /home/arluke --create-home arluke;
echo '%wheel ALL=(ALL:ALL) ALL' > /etc/sudoers.d/00_wheel;
passwd arluke
Configure Networking Packages
echo AllowGroups ssh-users > /etc/ssh/sshd_config.d/10-AllowGroups.conf;
systemctl enable NetworkManager sshd
Update appropriate hooks in /etc/mkinitcpio.conf
HOOKS=(base systemd autodetect microcode modconf kms keyboard sd-vconsole block sd-encrypt filesystems fsck)
Set kernel commandline options for encryption and btrfs root in /etc/cmdline.d/root.conf
rd.luks.name=${DEVICE_UUID}=root root=/dev/mapper/root rootflags=subvol=@ rw rootfstype=btrfs rd.shell=0 rd.emergency=reboot rd.luks.options=discard
Unified Kernel Image (UKI)
Create UKI key config: /etc/kernel/uki.conf
[UKI]
OSRelease=@/etc/os-release
PCRBanks=sha256
[PCRSignature:initrd]
Phases=enter-initrd
PCRPrivateKey=/etc/kernel/pcr-initrd.key.pem
PCRPublicKey=/etc/kernel/pcr-initrd.pub.pem
Generate UKI keys
ukify genkey --config=/etc/kernel/uki.conf
Update the preset file to enable UKI: /etc/mkinitcpio.d/linux.preset
# mkinitcpio preset file for the 'linux' package
#ALL_config="/etc/mkinitcpio.conf"
ALL_kver="/boot/vmlinuz-linux"
PRESETS=('default' 'fallback')
#default_config="/etc/mkinitcpio.conf"
#default_image="/boot/initramfs-linux.img"
default_uki="/efi/EFI/Linux/arch-linux.efi"
default_options="--splash /usr/share/systemd/bootctl/splash-arch.bmp"
#fallback_config="/etc/mkinitcpio.conf"
#fallback_image="/boot/initramfs-linux-fallback.img"
fallback_uki="/efi/EFI/Linux/arch-linux-fallback.efi"
fallback_options="-S autodetect"
Create EFI boot directories and install bootloader files
mkdir -p /efi/EFI/Linux
mkinitcpio -p linux
bootctl install
Secure Boot
If your system secure boot is not already in setup mode, reboot into BIOS and make it so.
sudo sbctl status
sudo sbctl create-keys
sudo sbctl enroll-keys
sudo sbctl verify
sudo sbctl sign -s /efi/EFI/BOOT/BOOTX64.EFI;
sudo sbctl sign -s /efi/EFI/Linux/arch-linux-fallback.efi;
sudo sbctl sign -s /efi/EFI/Linux/arch-linux.efi;
sudo sbctl sign -s /efi/EFI/systemd/systemd-bootx64.efi
- Reboot and enable secure boot in BIOS
sudo sbctl status
Post-Install Stuff
This section is largely a notepad for me to remember application and other important settings.
Packages
sudo pacman -Sy 7zip base-devel curl fastfetch gdisk git less nftables pciutils powertop unzip vlc wget zip
Fonts
sudo pacman -Sy noto-fonts noto-fonts-extra ttf-arimo-nerd ttf-font-awesome
yay (aur helper)
git clone https://aur.archlinux.org/yay.git ~/git/yay
cd ~/git/yay
makepkg -si
Graphics Configuration
AMD
sudo pacman -S mesa vulkan-radeon
NVIDIA
[!IMPORTANT] The particular package you require will depend on the generation of your GPU architecture. See the NVIDIA ArchWiki page for further detail.
sudo pacman -Sy nvidia-open nvidia-utils
Update /etc/mkinitcpio.conf
to load modules during initramfs
MODULES=(... nvidia nvidia_modeset nvidia_uvm nvidia_drm ...)
sudo reboot
[!IMPORTANT] There are two kernel parameters for the nvidia_drm module to be considered: modeset and fbdev. Both are enabled by default when using the nvidia-utils package. Both are required for Hyprland on Linux 6.11 or later.
Verify these both output 'Y':
sudo cat /sys/module/nvidia_drm/parameters/modeset;
sudo cat /sys/module/nvidia_drm/parameters/fbdev
If not...
sudo echo options nvidia_drm modeset=1 fbdev=1 > /etc/modprobe.d/nvidia-drm.conf
Set maximum power limit at boot: /etc/systemd/system/nvidia-power-limit.service
[Unit]
Description=Set NVIDIA GPU Power Limit
[Service]
Type=oneshot
ExecStart=/usr/bin/nvidia-smi -pl 320
[Install]
WantedBy=multi-user.target
sudo systemctl enable nvidia-power-limit.service
Audio
Install audio packages. pipewire
and pipewire-pulse
are installed in lieu of pulseaudio
.
sudo pacman -Sy alsa-firmware alsa-utils pipewire pipewire-alsa pipewire-jack pipewire-pulse wireplumber pavucontrol;
systemctl --user enable pipewire pipewire-pulse wireplumber
Set default device in /etc/asound.conf
, Where $card
is the card number output from aplay -l
defaults.pcm.card ${card}
defaults.ctl.card ${card}
Open pavucontrol
and set SSL 2+ MkII profile to "Pro Audio" to split channels and isolate the mic
Desktop Environment
KDE Plasma
sudo pacman -Sy sddm plasma konsole dolphin kate
sudo systemctl enable sddm
Hyprland
sudo pacman -Sy hyprland hyprlock hyprpaper kitty sddm waybar wofi
NVIDIA environmental variables: ~/.config/hypr/hyprland.conf
env = LIBVA_DRIVER_NAME,nvidia
env = __GLX_VENDOR_LIBRARY_NAME,nvidia
env = NVD_BACKEND,direct
Electron Apps: ~/.config/hypr/hyprland.conf
[!Warning] This can cause issues like being unable to assign keybinds in Discord vs the default running on xwayland. It's better to use as a flag for individual applications. Needs further investigation.
env = ELECTRON_OZONE_PLATFORM_HINT,auto
Applications
kitty (terminal)
sudo pacman -Sy kitty
On first SSH into system, use `kitten ssh user@hostname'
gnome-keyring
Secrets management in Hyprland.
sudo pacman -Sy gnome-keyring libsecret seahorse
gnome-text-editor
sudo pacman gnome-text-editor
nautilus
sudo pacman nautilus
discord
sudo pacman -Sy discord noto-fonts-extra
piper
Mouse configuration for Logitech devices (must be USB connected)
sudo pacman -Sy piper
obsidian
sudo pacman -Sy obsidian
keyd (remapping inputs)
sudo pacman -Sy keyd
Gaming
gamescope
Tweaks
[!CAUTION] These are tweaks for my system that I have found fix various performance issues. Use at your own risk.
vim /etc/sysctl.d/50-coredump.conf
# disable core dumps
fs.suid_dumpable=0
kernel.core_pattern=|/bin/false
vim /etc/sysctl.d/90-vm.parameters.conf
# reduce disk swapping
vm.swappiness = 10
# set dirty cache size
vm.dirty_bytes = 4194304
vm.dirty_background_bytes = 4194304