Installing Arch with LUKS and Btrfs (EFI)

NOTE: This post has been updated 2017-05-30 to use systemd-boot instead of GRUB.
NOTE: This post has been updated 2019-03-08 to skip using LVM since Linux kernel 5.0 allows swap file on Btrfs. Also using systemd-init.

I did the steps below to install my Arch for the first time, because I wanted to use Btrfs and LUKS, and also enable swap.

Start Installation CD/USB.
Set up keymap (see available keymaps with ls /usr/share/kbd/keymaps/i386/qwerty):
loadkeys sv-latin1
And start dhcp-request if you haven’t received an IP-address (check with ip addr):
dhcpcd
And now the fun part, partitioning!
Open up gdisk to create partitions for EFI and /boot:
gdisk /dev/sda
o (Create a new empty GUID partition table (GPT))
Proceed? Y

Create partitions:
n (Add a new partition)
Partition number 1
First sector 2048 (default)
Last sector +512M
Hex code EF00

n (Add a new partition)
Partition number 2
First sector 2099200 (default)
Last sector (press Enter to use remaining disk)
Hex code 8300

It should look something like this (print with p):
Number Start (sector) End (sector) Size Code Name
1 2048 1050623 512.0 MiB EF00 EFI System
2 1050624 500118158 238.0 GiB 8300 Linux filesystem

If everything looks good, save and quit:
w
Y

Set up the encryption container:
cryptsetup luksFormat /dev/sda2
Are you sure? YES
Enter passphrase (twice)

Open up the container:
cryptsetup --allow-discards --persistent open /dev/sda2 btrfs-system

Time to format everything:
mkfs.vfat -F32 /dev/sda1
mkfs.btrfs -L btrfs /dev/mapper/btrfs-system

Create Btrfs subvolumes:
mount /dev/mapper/btrfs-system /mnt
btrfs subvolume create /mnt/root
btrfs subvolume create /mnt/home
btrfs subvolume create /mnt/swap
umount /mnt
mount -o subvol=root,ssd,compress=lzo,discard /dev/mapper/btrfs-system /mnt
mkdir /mnt/{boot,home,swap}
mount -o subvol=home,ssd,compress=lzo,discard /dev/mapper/btrfs-system /mnt/home
mount -o subvol=swap,ssd,discard /dev/mapper/btrfs-system /mnt/swap

Time to create the swap:
truncate -s 0 /mnt/swap/swapfile
chattr +C /mnt/swap/swapfile
dd if=/dev/zero of=/mnt/swap/swapfile bs=1M count=8192 status=progress
chmod 600 /mnt/swap/swapfile
mkswap /mnt/swap/swapfile
swapon /mnt/swap/swapfile

And finally the /boot volume:
mount /dev/sda1 /mnt/boot

Installation:
pacstrap /mnt base base-devel btrfs-progs vim efibootmgr sudo zsh zsh-completions grml-zsh-config intel-ucode linux dhcpcd

Generate fstab:
genfstab -U /mnt > /mnt/etc/fstab
It should look something like this (genfstab -U /mnt):
UUID=5f55843f-d4ef-4c9c-bb43-d6ceb0d99c4d / btrfs rw,relatime,ssd,compress=lzo,space_cache,subvol=root,discard 0 0
UUID=5f55843f-d4ef-4c9c-bb43-d6ceb0d99c4d /home btrfs rw,relatime,ssd,compress=lzo,space_cache,subvol=home,discard 0 0
UUID=5f55843f-d4ef-4c9c-bb43-d6ceb0d99c4d /swap btrfs rw,relatime,ssd,space_cache,subvol=swap,discard 0 0
/swap/swapfile none swap defaults 0 0
UUID=AB0E-6CD2 /boot vfat rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro 0 2

Setting up stuff:
arch-chroot /mnt /bin/zsh
echo computer_name > /etc/hostname
chsh -s /bin/zsh
ln -sf /usr/share/zoneinfo/Europe/Stockholm /etc/localtime (See available timezones with ls /usr/share/zoneinfo)
vim /etc/locale.gen (uncomment en_GB.UTF-8 and sv_SE.UTF-8, or other locales that you want)
locale-gen
echo LANG=en_GB.UTF-8 > /etc/locale.conf
echo KEYMAP=sv-latin1 > /etc/vconsole.conf
passwd

Change/add the following to /etc/mkinitcpio.conf:
MODULES=(crc32c-intel)
HOOKS=(base systemd autodetect modconf block sd-encrypt btrfs resume filesystems keyboard fsck)

Generate mkinitcpio:
mkinitcpio -p linux

Run the command below to initialize systemd-boot, the path is your EFI-partition.

bootctl --path=/boot install

Run the following command to get the UUID of your disk, this is needed for systemd-boot:

lsblk -o name,uuid
NAME UUID
sda
├─sda1 AB0E-6CD2
└─sda2 b6cde26f-a4de-4f2e-b973-57c8fbe8813b
└─btrfs-system 5f55843f-d4ef-4c9c-bb43-d6ceb0d99c4d

Look for “sda2” and take note of the UUID of this partition.

Create the file /boot/loader/entries/arch.conf with the following content, or as you have your partitions set up:
title Arch Linux
linux /vmlinuz-linux
initrd /intel-ucode.img
initrd /initramfs-linux.img
options rd.luks.name=b6cde26f-a4de-4f2e-b973-57c8fbe8813b=btrfs-system luks.options=discard root=/dev/mapper/btrfs-system rw rootflags=subvol=root quiet

Edit the file /boot/loader/loader.conf:
timeout 3
default arch.conf

Done, rebooting time!
exit
umount -R /mnt
reboot

Installing KDE (personal preferences, might not apply to your setup!):
systemctl start dhcpcd (Starts DHCP so that you can download packages)
pacman -S networkmanager sddm
systemctl enable NetworkManager sddm
useradd -m -g users -G wheel username
passwd username

Add your user to sudo (edit /etc/sudoers):
username ALL=(ALL) ALL
Intel-specific GPU drivers and xorg. You might have to change xf86-video depending on your GPU vendor or if you want Wayland instead:
pacman -S xf86-video-intel xorg-server (for laptops: xf86-input-synaptics)
pacman -S plasma-meta ttf-dejavu ttf-droid ttf-liberation ttf-freefont konsole (select defaults on package selections)

Optional packages that you might want:
pacman -S kate pulseaudio yakuake firefox thunderbird dolphin ark chromium kodi feh conky firewalld unrar unzip zip git pavucontrol nfs-utils alsa-utils mpv openssh gimp spectacle lm_sensors redshift bind-tools whois krdc freerdp kcalc
If you want to install steam you must enable multilib, edit /etc/pacman/ and uncomment:
[multilib]
Include = /etc/pacman.d/mirrorlist

Install Steam:
pacman -Sy steam
And finally the last reboot!
reboot

After reboot, change login shell in the top-left to Plasma, and login.

All done! Now install everything else you might want :)

If you did something wrong and the OS doesn’t start correctly, you can start the USB/CD again and write the following to mount all things again:
loadkeys sv-latin1
cryptsetup luksOpen /dev/sda2 btrfs-system
mount -o subvol=root,ssd /dev/mapper/btrfs-system /mnt
mount -o subvol=home,ssd /dev/mapper/btrfs-system /mnt/home
mount -o subvol=swap,ssd /dev/mapper/btrfs-system /mnt/swap
swapon /mnt/swap/swapfile
mount /dev/sda1 /mnt/boot
arch-chroot /mnt /bin/zsh

Sources:
My very good friend Dezponia
https://wiki.archlinux.org/index.php/Installation_guide
https://wiki.archlinux.org/index.php/Swap#Swap_file
https://wiki.archlinux.org/index.php/btrfs
https://wiki.archlinux.org/index.php/Mkinitcpio#Common_hooks