GabMus's Dev Log

Arch Guide

Feel free to contribute to this guide! Browse the source on GitLab

Configurations and todos to make your Arch Linux the best Arch Linux


Make an encrypted install

NOTE: In this tutorial I will assume you’re working with a single drive indicated as ${DISK}. I will refer to ${DISK}1, ${DISK}2 etc as partition 1, partition 2 and so on. If you want to copy paste these commands, you can if you set the DISK variable in your shell to something like /dev/sda. If you have an nvme drive you CANNOT do this, since an nvme drive is indicated as /dev/nvme0n1 while partitions are indicated as /dev/nvme0n1p1, /dev/nvme0n1p2 etc. I will also assume you want to install using UEFI/systemd-boot.

Raw partition table overview

Partition Format Mount point
${DISK}1 FAT32 /boot
${DISK}2 LUKS No direct mount point

Create a GPT partition table with parted as follows:

parted ${DISK}
mklabel gpt

Use gdisk to create the partitions. NOTE: I will write # press enter when I need you to just press the enter key without writing anything

gdisk ${DISK}
# press enter
# press enter
# press enter
# press enter
# press enter

Complete the setup as follows

# Format the first partition to *FAT32*.
mkfs.vfat -F32 ${DISK}1
# Format the second partition as a LUKS encrypted container
cryptsetup luksFormat --type luks2 ${DISK}2
# Open the just created container
cryptsetup open ${DISK}2 cryptlvm
# Create a physical volume on top of the opened LUKS container
pvcreate /dev/mapper/cryptlvm
# Create a volume group with a name you want (I usually choose MasterVolumeGroup)
# and add the previously created physical volume to it
vgcreate MasterVolumeGroup /dev/mapper/cryptlvm
# Create the logical volumes on the volume group for the root and home partitions
lvcreate -L 40G MasterVolumeGroup -n root
lvcreate -l 100%FREE MasterVolumeGroup -n home
# Format the newly created logical volumes
mkfs.ext4 /dev/MasterVolumeGroup/root
mkfs.ext4 /dev/MasterVolumeGroup/home
# Mount the filesystem
mount /dev/MasterVolumeGroup/root /mnt
mkdir /mnt/home
mkdir /mnt/boot
mount /dev/MasterVolumeGroup/home /mnt/home
mount ${DISK}1 /mnt/boot

Before proceeding with the installation, you have to edit /etc/mkinitcpio.conf as follows:

  • Add keyboard keymap after base udev autodetect in the HOOKS array
  • Add encrypt lvm2 after consolefont modconf block in the HOOKS array

Proceed with the remaining part of the installation as normal. Refer to Use systemd-boot to install the systemd-boot bootloader.

Use systemd-boot

Arch Wiki reference

Requires you to be able to boot in UEFI mode (not MBR).

You need to have a /boot partition formatted in FAT32 (usually I make it 400 MBs, even if it’s a little too much).

Assuming you have all your file systems mounted to their proper locations AND that you are already chroot-ed in your installed system.

sudo bootctl --path=/boot install

Create /boot/loader/entries/arch.conf like follows:

title		Arch Linux
linux		/vmlinuz-linux
# uncomment one of the two lines below to install the intel or amd microcode
# initrd		/intel-ucode.img
# initrd		/amd-ucode.img
initrd		/initramfs-linux.img
# uncomment `nvidia-drm.modeset=1` if you want to enable nvidia drm kernel mode setting
options		root=UUID=ROOT_PARTITION_UUID rw quiet # nvidia-drm.modeset=1
# use the following options row in alternative to this ^^^ one if you have an encrypted setup
# options cryptdevice=UUID=ENCRYPTED_PARTITION_UUID:cryptlvm root=/dev/MasterVolumeGroup/root rw quiet

Where ROOT_PARTITION_UUID or ENCRYPTED_PARTITION_UUID can be obtained from the command lsblk -f (use the UUID of the partition mounted as /).

You may want to edit /boot/loader/loader.conf to set a timeout (format: timeout TIME_IN_SECONDS) and to add a line that says default arch-*.

Install systemd-boot-pacman-hookAUR to automatically update systemd-boot.

Microcode updates

Arch wiki reference


sudo pacman -S amd-ucode

Edit /boot/loader/entries/arch.conf so that the first initrd line is the following:

initrd        /amd-ucode.img


sudo pacman -S intel-ucode

Edit /boot/loader/entries/arch.conf so that the first initrd line is the following:

initrd        /intel-ucode.img

Compress initramfs with lz4

Make sure lz4 is installed.

Edit /etc/mkinitcpio.conf:

  • Add lz4 lz4_compress to the MODULES list (delimited by ())
  • Uncomment or add the line saying COMPRESSION="lz4"
  • Add a line saying COMPRESSION_OPTIONS="-9"
  • Add shutdown to the HOOKS list (delimited by ())

Run sudo mkinitcpio -p linux to apply the mkinitcpio.conf changes.

Limit journald log size

Edit /etc/systemd/journald.conf:

  • Uncomment SystemMaxUse= and append 200M (or any size you like).

Disable core dumps

To improve performance and save disk space.

Edit /etc/systemd/coredump.conf, under [Coredump] uncomment Storage=external and replace it with Storage=none. Then run sudo systemctl daemon-reload. This alone disables the saving of coredumps but they are still in memory.

If you want to disable core dumps completely add * hard core 0 to /etc/security/limits.conf.

Enable deep sleep suspension mode

Verify that you’re using the inefficient s2idle sleep state before continuing:

cat /sys/power/mem_sleep
Inefficient Efficient
[s2idle] deep s2idle [deep]

Add mem_sleep_default=deep to the kernel command line arguments.

Change IO Scheduler

Change CPU governor

Arch Wiki reference

sudo pacman -S cpupower

To change the governor for the current session run sudo cpupower frequency-set -g performance.

To change the governor on boot create a systemd service.

Create /etc/systemd/system/cpupower.service:

Description=Set CPU governor to performance

ExecStart=/usr/bin/cpupower -c all frequency-set -g performance


Finally run sudo systemctl enable cpupower.service.

NB: the default governor is powersave and you may want to leave it as it is.

Create /etc/udev/rules.d/50-scaling-governor.rules as follows:

SUBSYSTEM=="module", ACTION=="add", KERNEL=="acpi_cpufreq", RUN+=" /bin/sh -c ' echo performance > /sys/devices/system/cpu/cpufreq/policy0/scaling_governor ' "

Setting up Plymouth

NOTE: this setup implies that you use paru (AUR helper), gdm (display manager), and the default arch kernel.

paru -S plymouth-git gdm-plymouth

Edit /etc/mkinitcpio.conf:

  • In HOOKS after base udev insert plymouth
  • If you’re using encryption, in HOOKS replace encrypt with plymouth-encrypt
  • In MODULES insert your GPU driver module name as first item
    • For Intel GPUs: i915
    • For AMD GPUs: radeon (note: this is untested)
    • For NVIDIA GPUs: nvidia (note: this is untested)
    • For KVM/qemu VMs: qxl

Edit /boot/loader/entries/arch-linux.conf: add these arguments in the kernel options (append to the options section): quiet splash loglevel=3 rd.udev.log_priority=3 vt.global_cursor_default=1

sudo systemctl disable gdm
sudo systemctl enable gdm-plymouth
sudo mkinitcpio -p linux

Create a swap file

Arch Wiki reference

A form of swap is required to enable hibernation.

In this example we will allocate a 8G swap file.

sudo dd if=/dev/zero of=/home/swapfile bs=1M count=8192
sudo chmod 600 /home/swapfile
sudo mkswap /home/swapfile
sudo swapon /home/swapfile # this enables the swap file for the current session

Edit /etc/fstab adding the following line:

/home/swapfile none swap defaults 0 0

Removing the swap file if not necessary/wanted anymore

sudo swapoff -a

Edit /etc/fstab and remove the swapfile entry, and finally:

sudo rm -f /home/swapfile

Alternative route

Use systemd-swap for automated and dynamic swapfile allocation and use. Consult the GitHub project page for more info.

Enable Hibernation

Arch Wiki reference

Enable magic sysreq

Add this line to a file inside /etc/sysctl.d/ (ie: 99-sysctl.conf)


Enable weekly fstrim

sudo systemctl enable fstrim.timer

Package Management

Switch to better mirrors

Arch Wiki reference

sudo pacman -S reflector
sudo reflector --latest 200 --protocol http --protocol https --sort rate --save /etc/pacman.d/mirrorlist

Enable colors in pacman

Edit /etc/pacman.conf and uncomment the row saying Color

Enable parallel compilation and compression

Edit /etc/makepkg.conf:

  • Add the following row (replace 7 with CPU threads-1): MAKEFLAGS="-j7"
  • Edit the row saying COMPRESSXZ=(xz -c -z -) to COMPRESSXZ=(xz -c -z - --threads=0)
  • sudo pacman -S pigz and edit the row saying COMPRESSGZ=(gzip -c -f -n) to COMPRESSGZ=(pigz -c -f -n)

Install flatpaks in user directory with GNOME Software by default

gsettings set install-bundles-system-wide false

Use another computer as repository

Arch wiki reference

If you happen to run several Arch boxes on your LAN, you can share packages so that you can greatly decrease your download times

On the source computer install darkhttpd and run:

sudo ln -s /var/lib/pacman/sync/*.db /var/cache/pacman/pkg
sudo -u http darkhttpd /var/cache/pacman/pkg --no-server-id

On the destination computer edit /var/pacman.d/mirrorlist and insert Server = http://<source_machine_ip>:8080 as the first line of the file, replacing <source_machine_ip> with the ip of your source computer (to get a computer’s ip run ip -c a).

You’re all set up. Once you’re done, close darkhttpd on the source computer and comment/delete the line you just added on the destination computer.

This could be useful if you have multiple machines on the same LAN, maybe sharing a slow connection, or even if you want to make an arch installation without an internet connection.


Network printing

For good measure when using CUPS, make sure you have installed all cups packages I recommend below. They are all included in the commonpackages file in this repo.

foomatic-db foomatic-db-engine foomatic-db-gutenprint-ppds foomatic-db-nonfree foomatic-db-nonfree-ppds foomatic-db-ppds gutenprint cups cups-filters cups-pdf cups-pk-helper

Also make sure that your user is part of these 3 groups:

  • sys
  • lp
  • cups

In one command: sudo usermod -aG sys,lp,cups $USERNAME.

Install nss-mdns.

Edit /etc/nsswitch.conf adding mdns_minimal [NOTFOUND=return] right before resolve [!UNAVAIL=return].

hosts: ... mdns_minimal [NOTFOUND=return] resolve [!UNAVAIL=return] dns ...
#          ------------------------------

Do a sudo systemctl start avahi-daemon.service (or restart if necessary). Also do sudo systemctl restart org.cups.cupsd.service and sudo systemctl restart cups-browsed.service for good measure.

If you have the correct drivers for the network printer, it should now be usable. Also, if GUI printer managers fail, try the CUPS web interface at localhost:631.



Copy monitor layout from user to GDM

GDM doesn’t know how you configure your monitors. It just keep its default configuration and most of the time it’s not the same of how you have them configured in your session.

To copy your user’s monitors configuration over to GDM, use these commands:

sudo cp $HOME/.config/monitors.xml /var/lib/gdm/.config/
sudo chown gdm:gdm /var/lib/gdm/.config/monitors.xml



Create /etc/X11/xorg.conf.d/99-amdgpu.conf with the following content:

Section "Device"
     Identifier "AMD"
     Driver "amdgpu"
     Option "TearFree" "true"

AMDGPU Variable Refresh Rate

Create or edit /etc/X11/xorg.conf.d/99-amdgpu.conf and make sure it has the row saying Option "VariableRefresh" "true". It’s also suggested that you enable TearFree along with VariableRefresh:

Section "Device"
     Identifier "AMD"
     Driver "amdgpu"
     Option "TearFree" "true"
     Option "VariableRefresh" "true"

AMDGPU early kernel mode setting

Edit /etc/mkinitcpio.conf prepending to the MODULES list (delimited by ()) the following: amdgpu.

Run sudo mkinitcpio -P.

AMDGPU enable overclocking

Add the following option to your kernel command line arguments: amdgpu.ppfeaturemask=0xffffffff.

If you’re using systemd-boot add the line above at the end of the options line.

To overclock your AMD GPU I suggest using CoreCtrl.

Override Vulkan ICD

Set the environment variable VK_ICD_FILENAMES to the absolute path of one of the json files in /usr/share/vulkan/icd.d/.

AMDGPU Pro Vulkan ICD seems to be glitchy as of now (2019-08-27 13:41:47+02:00). /usr/share/vulkan/icd.d/radeon_icd.x86_64.json seems to be working fine.


NVIDIA DRM kernel mode setting

Arch Wiki reference

Edit /boot/loader/entries/arch.conf appending nvidia-drm.modeset=1 to the options row.

Edit /etc/mkinitcpio.conf prepending to the MODULES list (delimited by ()) the following: nvidia nvidia_modeset nvidia_uvm nvidia_drm.

Run sudo mkinitcpio -p linux to apply the mkinitcpio.conf changes.

Add a pacman hook to rebuild initramfs after an NVIDIA driver upgrade, create /etc/pacman.d/hooks/nvidia.hook:


Exec=/usr/bin/mkinitcpio -P

NB: Make sure the Target package set in this hook is the one you have installed (nvidia, nvidia-lts or some other different or legacy driver package name).

Edit /etc/gdm/custom.conf uncommenting the row that says WaylandEnable=false (enabling DRM kernel mode setting usually improves performance but enables NVIDIA Wayland support for GNOME, but currently NVIDIA Wayland performance is terrible and makes for an unusable experience. While this option is not mandatory, it’s highly recommended).

Fix screen tearing with NVIDIA GPUs

First you need a base xorg config file to work with. To obtain it, run nvidia-xconfig -o ./nvidia-xorg.conf.

Open it up and strip out everything but the Device and Screen sections.

In the Device section you may want to add a line like this: BoardName "<GPU Model>". For example, with my GTX 960 I have BoardName "GeForce GTX 960".

In the Screen section, delete everything but the lines saying Identifier, Device and Monitor. In the same section add the following lines:

Option "AllowIndirectGLXProtocol" "off"
Option "TripleBuffer" "on"

Finally, again in the Screen section, add a line that’s a little bit complex, so we can build it up step by step.

You have to write a comma separated list of the video outputs that you use, corresponding resolutions, refresh rates and offsets. You can make this process easier by using xrandr.

In a terminal, type in xrandr | grep " connected". You will see something like this:

HDMI-0 connected 1920x1080+2560+360 (normal left inverted right x axis y axis) 521mm x 293mm
DP-2 connected primary 2560x1440+0+0 (normal left inverted right x axis y axis) 597mm x 336mm

The initial part of the line is always Option "metamodes" .

Following, inside quotes, write "<output name>: <resolution width>x<resolution height>_<refresh_rate> +<offset x>+<offset y> {ForceCompositionPipeline=On, ForceFullCompositionPipeline=On}, <repeat for all outputs>".

For reference, here’s my line: Option "metamodes" "DP-2: 2560x1440_60 +0+0 {ForceCompositionPipeline=On, ForceFullCompositionPipeline=On}, HDMI-0: 1920x1080_60 +2560+360 {ForceCompositionPipeline=On, ForceFullCompositionPipeline=On}".

Again, for reference, here’s my full file:

Section "Device"
        Identifier "Device0"
        Driver     "nvidia"
        VendorName "NVIDIA Corporation"
        BoardName  "GeForce GTX 960"

Section "Screen"
    Identifier     "Screen0"
    Device         "Device0"
    Monitor        "Monitor0"
    Option         "AllowIndirectGLXProtocol" "off"
    Option         "TripleBuffer" "on"
    Option         "metamodes" "DP-2: 2560x1440_60 +0+0 {ForceCompositionPipeline=On, ForceFullCompositionPipeline=On}, HDMI-0: 1920x1080_60 +2560+360 {ForceCompositionPipeline=On, ForceFullCompositionPipeline=On}"

Once you have a file that looks like this, rename it to 20-nvidia.conf and move or copy it to /etc/X11/xorg.conf.d/.

NVIDIA Optimus

Arch Wiki reference

GNOME Wayland not available with Intel+NVIDIA GPUs

Edit /etc/environment and add MUTTER_ALLOW_HYBRID_GPUS=1


Use pipewire-pulse pulseaudio replacement

sudo pacman -S pipewire pipewire-pulse pipewire-alsa
systemctl --user enable pipewire pipewire-pulse

Rebooting is a good idea.

Noticeable audio delay on playback start

Edit /etc/pipewire/media-session.d/media-session.conf, comment line saying suspend-node inside an array called default.

Additionally edit /etc/pipewire/media-session.d/alsa-monitor.conf, uncomment the line saying session.suspend-timeout-seconds = 5 and change its value to 0.

Audio cutting out when multiple streams start playing


Edit /etc/pipewire/media-session.d/alsa-monitor.conf, uncomment the line saying api.alsa.headroom = 0 and change its value to 1024.

Fix bluetooth audio

Arch Wiki reference

Prevent GDM from spawning pulseaudio: edit /var/lib/gdm/.config/pulse/client.conf like so:

autospawn = no
daemon-binary = /bin/true

Finally run:

sudo -ugdm mkdir -p /var/lib/gdm/.config/systemd/user
sudo -ugdm ln -s /dev/null /var/lib/gdm/.config/systemd/user/pulseaudio.socket

MPV hardware decoding (NVIDIA VDPAU)

Install nvidia-utils (or similar package depending on your nvidia driver) and libva-vdpau-driver.

Create or edit .config/mpv/mpv.conf:



Setup libvirt

sudo pacman -S libvirt ebtables dnsmasq bridge-utils virt-manager
sudo gpasswd -a $USERNAME libvirt
sudo gpasswd -a $USERNAME kvm
sudo systemctl enable libvirtd
sudo systemctl start libvirtd

Make sure to relogin after following the steps above. To create a network:

  • Open virt-manager
  • Click on QEMU/KVM
  • Click Edit > Connection Details in the menu
  • Click the Virtual Networks tab
  • Click the + (plus sign) button in the bottom left corner of the newly opened window
  • Name it whatever
  • Select NAT as Mode
  • Leave everything else as it is
  • Click finish
  • To start the network, select it in the sidebar and press the ▶️ (play icon) button
  • To stop the network, press the icon to its left with the 🛑 (stop street sign icon) button (note: the icons could be different depending on the theme)
  • To start the network on boot, select it in the sidebar and toggle the checkbox that says Autostart: On Boot

GNOME Adwaita theme for Qt apps

  • Install qt5ct from the repos and adwaita-qt from the AUR
  • Open up the qt5ct application and select your favorite Adwaita flavor with the default color scheme and press apply
  • Add the following to ~/.pam_environment:
  • Add the following to ~/.profile:

Enter your instance's address