My Arch Linux Setup
This post now has a new version that supersedes this one.
I’ve been a big fan of Arch Linux for a long time now. Though it is a lot of work to set up, it offers a great opportunity to learn exactly how everything fits together in a Linux system. There’s also that pleasant satisfaction when everything is finally set up exactly the way I like it. In the interest of making this process easier for both myself and others, I’ve written down my personal guide to setting up Arch Linux.
Overview
This guide is intended to be a companion to the official installation guide and not a replacement since I don’t plan on covering every detail here nor will I include the specific commands you need to run. You should follow both guides side-by-side and follow any linked documentation without prompting from me. In general, the ArchWiki is an excellent resource and honestly one of the biggest strengths of Arch Linux so feel free to consult it at any point. It’s even useful when you aren’t running Arch. In fact, I seriously recommend abandoning this guide and just following the installation guide by itself, but chances are that isn’t acceptable for you otherwise you wouldn’t be here.
Rather than just going through all the steps, I will focus on explaining the rationale behind my decisions. After all, the benefit of Arch is that you get to make the choice, and I would hate to completely take that away from you. Note that this guide is somewhat aimed at a VirtualBox setup so some of the choices may be non-ideal for a physical machine, though I will still cover some things that aren’t useful for a VM (full-disk encryption). Here are some of the key choices I made:
Boot process | UEFI |
Partitioning | / (encrypted with dm-crypt), /efi |
Boot loader | GRUB |
File system | btrfs |
Window manager | i3 |
Swap | Swap file or swap partition |
Networking | systemd-networkd and systemd-resolved |
Firewall | ufw |
Pre-installation
To start off, download an installation image.
VirtualBox Guest
If you are not installing Arch as a VirtualBox guest, you can skip this section. First, create a new VM in VirtualBox. There are a variety of settings you can configure as you like, but there are a few recommendations I would make.
First, enable EFI mode. Though it’s perfectly fine to stick to BIOS mode, most modern computers are using UEFI, so you might as well get used to it. If you do decide to stick with BIOS mode, be sure you choose a boot loader that supports it since some newer boot loaders only support UEFI.
Second, you’ll need to choose the disk size. Though it’s possible to resize things later (or add more drives if you use btrfs), it’s more convenient to ensure you have enough space from the beginning. Arch can be run very lightweight, but in my experience, 8 GB is as low as you’d want to go and still have an acceptable desktop environment. Even then, space will be tight if you start installing a lot of larger packages (LaTeX, fonts, etc.) and that’s not even including your own files. I personally go with 32 GB so I don’t need to worry too much about it. Obviously you’ll need more space if you have lots of personal files (documents, datasets, videos, etc.).
Finally, here are some less important options that I like to set.
- Enable the shared clipboard. This won’t work until we install the VirtualBox Guest Additions, but feel free to enable it early so you don’t forget.
- Set the amount of memory. Make sure not to exceed what your host system has available.
- Set the boot order. Chances are that the default is perfectly fine, but I usually remove everything except the optical drive and the hard disk, and then rearrange the optical drive to come first.
- Set the number of processors. You can set this to match the number of cores your computer has since the host and guest machine can share all the cores safely.
- Enable PAE/NX. This will enable Physical Address Extension which includes support for the no-execute bit which can provide additional security by preventing execution of code in data-only memory pages. I’m not actually sure enabling this alone is enough, but might as well do so.
- Set video memory to the maximum (128 MB). This is already a relatively small amount and will likely not be enough for graphics heavy workloads, so even a basic desktop environment might have trouble with anything less.
- Enable 3D acceleration. This will allow usage of your host system’s graphics card and will improve performance of programs that can take advantage of that (e.g. web browsers).
- If you are storing the VM’s hard drive on an SSD, mark the SSD attribute for the disk. This will tell the guest system that it is on an SSD so it can change its behavior to take advantage of that.
- Disable showing the mini toolbar in full-screen mode. This is just my personal taste, but I prefer not having any VirtualBox UI when in full-screen mode.
Finally, add the installation image to the VM.
Initial Steps
Boot the Arch Linux live installation which you will use to set up your actual
installation. Note that you may want to do everything inside tmux
so you
can scrollback to previous output1 and copy/paste between multiple
terminals.
Start off with the first several steps:
- Set the keyboard layout if needed.
- Set the console font if desired (I like
Lat2-Terminus16
which is justterminus-font
). - Confirm you are running in UEFI mode (unless you want to use BIOS instead).
- Confirm you have internet access.
- Enable NTP for the system clock.
Disk Partitioning
There are many ways to partition the disk for a Linux install depending on your needs. This guide will aim to keep things simple, but before we start, there are a few things to keep in mind.
First, using GPT is recommended over MBR for booting in UEFI mode since it is more flexible and better supported by motherboards and operating systems implementing UEFI2. Second, UEFI requires an EFI system partition since that is where UEFI will look for boot loaders to run. Given that we are trying to keep it simple, we will have 2 main partitions:
- EFI system partition
- Encrypted root directory partition
Next, you’ll need to decide if you want a swap partition or a swap file (or none in which case you can skip this). Though swap partitions are the easiest way to get swap space, they also aren’t very flexible since it’s harder to move, shrink, or expand a partition (unless you use LVM), and you’ll need to set up encryption for the swap partition separately. In contrast, swap files can be dealt with just like any other file and will naturally be encrypted if they are stored on an encrypted partition. However, their setup is more complicated, and if you choose to run btrfs and wish to add more disks in the future, btrfs doesn’t support swap files on filesystems with multiple disks.
If you want a swap file, then you don’t need to do anything else with your partitioning. Otherwise, you’ll need to add a swap partition now. I’d recommend putting it after your root directory partition so that you can expand/shrink it by shrinking/expanding your root directory partition and then moving the swap partition. Otherwise, you’ll have to move your root directory partition which is a huge pain and much riskier.
Note that for a VM, it’s probably easier to set up a separate virtual drive solely for a swap partition since you can resize the drive quite easily.
Storing /boot
on Root Partition
In this guide, we will be keeping our kernel and initramfs (aka the /boot
directory) in the root directory partition so that when we take a btrfs
snapshot, it will encompass the entire system including the kernel. This is
important because usually kernel modules are not installed under /boot
, so if
we kept the kernel in a separate partition, snapshots of the kernel would not
be taken and restored in sync with the kernel modules which will break things.
However, this will cause trouble if you want to encrypt your root partition
since your boot loader will now need to decrypt the partition to get access to
your kernel. Currently GRUB is the only boot loader that can unlock a LUKS
partition. If you’d prefer using a different boot loader or generally don’t
want to deal with the hassle, then I’d recommend keeping /boot
unencrypted by
either storing it in the EFI system partition, making a separate boot
partition, or just not encrypting your root partition.
Note that having the kernel encrypted can stop an attacker from directly modifying the kernel. However, this won’t stop a particularly determined attacker since they can modify the boot loader instead which will give them access to your system after you decrypt it3.
Running the Partitioning Tool
There are many tools that can be used to partition the drive so choose whatever
suits you (if you use fdisk
, be sure to switch to GPT). The ArchWiki
recommends making the EFI system partition 260 MB which I believe comes from
the minimum FAT32 partition size on certain drives.
Use the remainder of the disk as the second partition which will be storing the
root directory.
Disk Encryption
Though I don’t always do this, this guide will use dm-crypt to encrypt the
entire root directory partition. This does cause some pain (e.g. must use
GRUB if also encrypting /boot
, requires password on boot, harder to
configure), but it’s really the only way to ensure all your data is safe if
your hard drive is stolen or directly accessed. Otherwise, if you only encrypt
your /home
partition, it’s very easy for personal data to get leaked in
logs/caches or you may accidentally put personal data in an unencrypted
partition.
Now the complicated part. Basically, you want to follow these instructions when you encrypt the root partition to ensure GRUB can decrypt it. However, those instructions also include setting up LVM when we just want to set up a simple partition encryption like in these instructions. You’ll need to follow some mixture of the two, so be sure to read both instructions fully before taking any steps. Note that the last steps of the instructions involve setting up your initramfs and boot loader which we will do later in this guide so hold onto those steps.
If you decided to go with a separate swap partition, you’ll also need to encrypt that as well. If you want the kernel to resume successfully from it, you’ll also need to configure the swap partition to be decrypted. See these instructions.
Format Partitions
Next, you will need to format each partition with the correct file system.
The EFI system partition should be FAT32
and swap should be formated with mkswap
, but your root directory partition
can be whatever you like. If you encrypted your root directory partition,
ensure that you are formatting the decrypted mount point (e.g.
/dev/mapper/cryptroot
) rather than the partition itself otherwise you will
destroy the encryption. In this guide, we will be using btrfs since it
supports snapshots and automatic compression.
Now before we get any further, I need to acknowledge that btrfs has a pretty bad reputation for losing data which is pretty much the worst possible thing a file system could do. This is especially ironic since it is a copy-on-write file system. Usually such file systems are considered safer from corruptions since their operations are naturally atomic due to simply never overwriting previous data/metadata. I believe a lot of the issues were from people using btrfs with a RAID5/6 setup which even now isn’t supported, but there are definitely enough horror stories to warrant caution. Anyway, I don’t have much experience with btrfs, but it has a lot of nice features and enough people saying good things about it (it’s now the default for Fedora) for me to justify using it. Still, if its reputation scares you off, feel free to use a different file system (e.g. ZFS is another CoW file system that is largely considered to be better in every way except it is optimized for enterprise usage and has unfriendly licensing).
Mounting Filesystems
Next, we need to decide how our newly formatted partitions will be mounted. If
you didn’t choose to use btrfs, the straightforward scheme is to just mount
your new root directory at /mnt
and then mount the EFI system partition at
/mnt/efi
(or at /mnt/boot
if you want to put your kernel image in the EFI
system partition). However, with btrfs, we have some additional options to
consider.
First, you should decide whether to mount the btrfs directory with
compression
enabled. I don’t have any hard data on this, but for a hard drive, enabling
compression is pretty much a no-brainer since disk IO is slow enough to make it
worth the CPU cost to reduce it. For SSDs though, it’s probably a performance
hit most of the time. Still, if disk space is more important to you, the
performance penalty
is likely worth it (e.g. our VM with only 32 GB of space). If performance is
still important, you could choose the LZO algorithm since it is the fastest,
but at that point, you should probably just not enable compression at all (or
even avoid btrfs since it is slower than ext4). If you do decide to enable
compression, you should mount with the option compress=zstd:1
since the ZSTD
algorithm seems better than the default ZLIB, and level 1 already provides
significant compression so more isn’t worth the additional overhead.
Next, you should mount with the noatime
option. In general, this is a
useful optimization for any file system when you don’t need access times for
your files, but this is especially true for btrfs since metadata updates are
implemented via copying the metadata which makes updating the access time even
more expensive.
Subvolume Layout
Before we start mounting things, we should figure out how we want to lay out our btrfs subvolumes (if you aren’t using btrfs, you can skip this section). Subvolumes act as directory-like mount points that maintain their own file tree even though they are all part of the same file system. Most usefully for us, subvolumes support snapshotting. In btrfs, a snapshot is just a subvolume that starts off with the file tree of another subvolume. Once the snapshot is created, its file tree is modified independently of the original subvolume i.e. writes to one subvolume will not affect files in the other. Cheap snapshotting is one of the main advantages of a copy-on-write file system.
To start off, here are a few basic approaches
to layout your btrfs subvolumes. Feel free to come up with your own, but here’s
the layout of my subvolumes and how they are mounted into the system.
Subvolumes are prefixed with @
and normal directories are suffixed with /
.
top-level -> /.btrfs
├── @home -> /home
├── @root -> /
├── snapshot/
│ ├── home/
│ │ ├── @2020-02-20T20:20:20
│ │ ├── @2021-02-21T21:21:21
│ │ └── @my_snapshot
│ └── root/
│ ├── @2002-02-02T02:02:02
│ ├── @2003-03-03T03:03:03
│ └── @before_install_foo
└── @swap
The /.btrfs
mount point exists to make it convenient to access all the other
subvolumes/snapshots. @home
and @root
are separate subvolumes since most of
the time you’d want to restore them separately from each other (e.g. I deleted
my documents vs I need to downgrade a package). The @swap
subvolume is for
storing a swap file since it requires that the containing subvolume is not
snapshotted or compressed (obviously you can omit this if you don’t want a swap
file).
To actually create this layout, you should first mount the btrfs top-level
subvolume somewhere so you can cd
in and start creating the subvolume and
directory structure. To continue with the rest of the installation, you should
mount everything we’ve set up. Here’s the layout for the above example:
@root
subvolume at/mnt
@home
subvolume at/mnt/home
- EFI system partition at
/mnt/efi
- btrfs top-level subvolume at
/mnt/.btrfs
@swap
subvolume at/mnt/swap
(we do need to disable compression for that subvolume, but doing it via mount options probably won’t work)
Installation
Next, you will use pacstrap
to install the necessary packages to the root
directory of your new system which is mounted at /mnt
. You should include
any additional packages that would be useful to have while you are setting up
everything else. Some packages I like to install early since they are pretty
helpful even without configuration:
btrfs-progs
- Provides user-space tools for working with btrfs. This package is basically
a necessity because when you generate the initramfs via
mkinitcpio
, it will be unable to run the fsck build hook without this.
- Provides user-space tools for working with btrfs. This package is basically
a necessity because when you generate the initramfs via
man-db
andman-pages
- The ubiquitous
man
command is the standard way to read documentation on various commands, programs, system calls, etc. Though most of these can be found online nowadays, nothing beats the convenience of having them right in your terminal. Theman-db
package provides theman
command andman-pages
provides Linux specific man pages.
- The ubiquitous
neovim
- Unless you want to use
echo
andsed
, there is no text editor included, so I highly recommend installing one. Obviously you can use whatever text editor you like, butneovim
is a great choice for people who are fans ofvim
since it is nearly drop-in compatible but has sensible defaults.
- Unless you want to use
tmux
- Having a terminal multiplexer allows you to have a scrollback buffer in the Linux console1 which is useful before you get a graphical environment set up. It also lets you open multiple terminals and copy/paste between them.
fish
- Though chances are you are already familiar with
bash
,fish
is a nice shell that includes advance features (syntax highlighting, auto-complete) without requiring any configuration. However, it is not POSIX compliant so scripts that don’t have a shebang are likely to break. Also, you’ll probably want to includepython
so it can parse man pages for more auto-completions. If you want something closer tobash
,zsh
is a good choice, but it requires a bit of configuration before it gets to the same level asfish
.
- Though chances are you are already familiar with
Next, you should run genfstab
as indicated in the installation guide. You may
want to first mount your swap partition and anything else you want in the final
system so that they’ll end up in the generated /etc/fstab
. Afterwards, you
will want to modify /etc/fstab
to remove the subvolid=
mount option for the
btrfs partition. This way, you can restore from a snapshot by a simple mv
of
the @root
subvolume to @root_old
and then taking a snapshot of the desired
snapshot and naming it @root
. If you leave the subvolid=
in, the mounting
will fail since the subvolume ID will be different.
After you’ve run arch-chroot
, you will now be acting as if you are inside the
system. You should set up the following next:
- Time zone
- Hardware clock
- Locale
- Keyboard layout
- Console font
- Root password
Networking
For a VM or a simple wired connection, the networking setup is pretty simple. The particular details might vary depending on the network card, but just using the basic systemd-networkd should be fine for most cases. You will also need systemd-resolved in order to resolve DNS requests (or an alternative DNS resolver if you prefer).
Wireless configuration is more complicated. NetworkManager is pretty standard, but I tend to use iwd nowadays. Otherwise, I don’t have much advice here so feel free to explore other solutions.
initramfs
Though pacstrap
already created an initramfs, it won’t actually work if you
need to decrypt the root directory partition when booting since it is missing
some configuration. The main thing we need to do is update the list of hooks.
Unless you have multiple encrypted partitions (e.g. swap partition) or a
detached LUKS header, it should be fine to stick with the encrypt
hook
instead of sd-encrypt
, but you will need to choose the latter if you do need
those features. sd-encrypt
will require you to switch out other hooks for
their systemd equivalents.
I’d also highly recommend including a key file in the initramfs so it can unlock the root and swap partition without you having to type in the password again. Be sure to keep the key file and the initramfs (including the fallback one) secure by setting the permissions so only the root user can read them.
Don’t forget to run mkinitcpio -P
otherwise your changes won’t take effect
and your system will still use the old initramfs likely causing your system to
fail to boot!
Boot Loader
The last thing we need to do before we can boot into our system is set up a
boot loader. Usually we’d have multiple choices here, but if you need a
bootloader that can both decrypt a LUKS partition and read btrfs, GRUB is our
only option. If you are not encrypting your /boot
, then you can go with a
boot loader that supports btrfs like rEFInd. If you aren’t using that either,
then systemd-boot
is simple, works pretty well, and is already installed by
default. The rest of this guide will assume you went with GRUB, but I would
recommend going with something simpler if you can.
Be sure to configure things correctly otherwise your system won’t boot. The instructions for GRUB are quite complicated. At a high level, you need to do the following:
- Set
GRUB_ENABLE_CRYPTODISK=y
- Run
grub-install
- Configure
/etc/default/grub
- Run
grub-mkconfig
Be sure to double check the resulting /boot/grub/grub.cfg
file to confirm it
sets the right kernel parameters for decrypting the root directory
and mounting the correct btrfs subvolume.
Finally, if you are installing this on a real machine, you should install the correct microcode for your CPU.
Reboot
Assuming nothing went wrong, you should have a functioning Arch Linux system,
so exit the chroot. Try running umount -R /mnt
to see if there is still some
process busy reading/writing to something (use fuser
to figure out who).
Finally, you should reboot the machine to see if your new OS boots up (don’t
forget to remove the installation image and consider changing the boot order to
try the hard disk first).
If things didn’t go so well, you’ll need to investigate what happened and try to fix it. Double check this guide and the installation guide to make sure you followed all the steps. I also recommend reading through the ArchWiki on topics related to the problem.
Post-installation
At this point, feel free to close this guide and do your own thing. Your system
can independently boot itself now, and you can install whatever you like via
pacman
. However, I would not consider this system to be complete since it
needs some work until it’s usable and secure enough for daily usage. As you may
have guessed, the rest of this guide is based on the official general
recommendations page which is usually what you would follow after finishing
the installation guide.
Snapshotting with Btrfs
Before we get started, we should go over how to take a snapshot with btrfs so you can restore things if you screw it up. If you aren’t using btrfs, this section doesn’t apply to you.
Check out man btrfs-subvolume
which explains the snapshot
command. You most
likely want to use the -r
flag to make the snapshot read-only to avoid
accidentally modifying it later. Taking a snapshot is very easy:
# cd /.btrfs
# btrfs subvolume snapshot -r @root snapshot/root/@$(date -Iseconds)
Restore from a snapshot by replacing the old subvolume with a new read-write snapshot of your chosen snapshot. Since we are mounting our subvolumes by path, you need to ensure the path of the restored snapshot is exactly the same as the original subvolume. If you are replacing the root directory, you should reboot to get the new snapshot mounted. For the home directory, you could maybe get away with remounting it live, but it’s probably safer to just reboot.
After you’ve confirmed that everything is good, you can delete the old
subvolume (feel free to keep a snapshot of it). Do not delete the old root
directory subvolume while it is still mounted. If you do so, you will lose
your entire root directory and be unable to run any programs including the
btrfs
command that you would need to fix this.
# cd /.btrfs
# mv @root @root_old
# btrfs subvolume snapshot snapshot/root/@chosen_snapshot @root
# reboot
# btrfs subvolume delete @root_old
Since I always forget all the commands, I usually write a README.md in
/.btrfs
describing all this and include a script for convenience.
User Account
Currently the only user is the root user which is not great to use regularly
since programs you execute will have much greater permissions than they
probably need. Creating your own user is pretty straightforward using the
useradd
command, but before you do that, consider setting up the skeleton
directory (defaults to /etc/skel
) since the files in that directory will be
directly copied to any new user’s home directory.
# useradd -m -G wheel <username>
# passwd <username>
# chfn <username>
-m
will create a home directory, and -G
adds the new user to the specified
groups. The wheel
group is an administrative group that gets additional
privileges thanks to polkit. passwd
sets the user’s password. chfn
lets
you set up some additional GECOS metadata which is used by some software.
Sudo
sudo
is a convenient way to run a program with root access without using
su
to switch to the root user. This is more secure since you can give higher
capabilities only to the commands that need it. Though sudo
can support more
complicated setups, I find that giving full access to the members of the
wheel
group is good enough for systems that have one or just a few users.
Start by installing the sudo
package. Next, using visudo
you can modify the
config to allow members of the wheel
group access to sudo
.
%wheel ALL=(ALL) ALL
I also recommend disabling the password input timeout since it is quite common
for a long-running script that runs sudo
to timeout if you don’t happen to be
around to type in the password. With this option enabled, you won’t have to
restart the entire script. Other ways of dealing with this (extending sudo
timeout or not requiring a password) are insecure.
Defaults passwd_timeout=0
Polkit
With sudo
set up, you should be able to do any administrative task that you’d
need to do, but for commands that are safe to run (e.g. poweroff
and
reboot
), it can be annoying having to type sudo
and your password every
time. That’s where polkit comes in. polkit is a framework for normal users to
communicate to privileged programs which essentially allows running certain
privileged commands without sudo
. Unlike sudo
, which grants an entire
process root access, polkit only provides access to specific functionality of
privileged programs which makes it more secure.
Start by installing polkit
. Luckily for us, poweroff
and reboot
are
already configured to not require a password if you are physically logged in
(e.g. not ssh
) and there are no other users logged in. For other
actions/rules, polkit considers members of the wheel
group to be administrators,
so it’s best to ensure your administrative accounts are members of wheel
.
Disable Root Login
With both sudo
and polkit configured, you do not need the root account
anymore, so you can make your system more secure by disabling root login.
Before you do so, log in as your new administrative user and ensure sudo
works. Double check these warnings
don’t apply to you, and then run the following:
# passwd -l root
You can still “login” as the root user by doing sudo -i
to get a root shell.
Note that if something goes wrong during boot, Linux will sometimes drop you in
a root shell, but if you disable root login, this will stop working. If this
worries you, then you should skip this step.
Pacman
As you’ve likely figured out by now, pacman
works just fine out of the box.
However, there are a few things you’d probably like to set up before you start
installing more things. Here are a few options in the pacman.conf
file you
may be interested in:
Color
: Enables color output in the terminal.ParallelDownloads
: Download multiple packages at the same time. The commented-out default of 5 is probably fine unless it isn’t enough to fully saturate your download bandwidth.
pacman
supports pre/post-transaction hooks
which allow you to run arbitrary commands before/after pacman
does anything.
You could create a hook to take a btrfs snapshot right before anything happens
(be sure to give it an alphabetically early name to ensure this) which makes it
easy to revert a bad upgrade. Note that the snapshot might be a bit finicky
since it will include pacman
’s lock file which you’ll need to manually
delete. Check out man alpm-hooks
for details on the syntax of the hook files.
If you don’t feel like doing all this manually, consider using Snapper and
follow these instructions.
Reflector
Reflector is a tool that can update the pacman
mirror list with the best
mirrors based on how fresh they are and their speed. Though the default
/etc/pacman.d/mirrorlist
file should work pretty well since it was already generated via Reflector,
mirrors do change over time and it’s convenient to set it up while you still
have the context.
After you install the reflector
package, update the
/etc/xdg/reflector/reflector.conf
to have the parameters you desire. I
personally would recommend setting these options:
--protocol https
: The HTTP protocols are generally faster since the connection can be reused for multiple downloads. I go with HTTPS for the additional security (probably not necessary since packages are signed, but it doesn’t hurt to be cautious).--country US
: Only consider mirrors in your country since they are likely to be close (use--list-countries
to see the list of countries).--latest 25
: Find the 25 most up-to-date mirrors. Any mirror that is up-to-date enough is acceptable, but might as well pick the latest 25. I prefer this over--score
since the score also includes the RTT from the Arch Linux servers to the mirror which isn’t very useful since your computer likely isn’t in the same location.--sort rate
: Amongst the selected mirrors, sort them by their speed so you’ll use the fastest mirror first for downloading packages.
Alternatively you could use --fastest
, --age
, and --sort age
instead of
--latest
and --sort rate
. This essentially prioritizes speed over being
up-to-date, but if you pick a low enough --age
, the result will be similar.
Once the config file is set up, you can start the systemd service
reflector.service
to update your mirrors. You can take a look at the updated
/etc/pacmand.d/mirrorlist
file to confirm it worked. Note that you could
enable this service to have it run on every boot, but if you really want to
update your mirrors regularly, I would recommend enabling the systemd timer
(reflector.timer
) instead since you really don’t need to update your mirrors
that often.
Swap
Though you can probably get pretty far without any swap (especially if you have tons of memory), it’s best to have some just in case you exhaust all your RAM. Otherwise, programs will get killed by the kernel and you’ll be at higher risk of locking up your entire system.
If you wish to set up hibernation, setting your swap space too small may cause hibernation to fail if there is too much RAM to save. In practice, the kernel will do significant compression so there’s a decent chance it’ll fit even if your swap space is smaller than your RAM.
Swap Partition
If you want to use a swap partition, hopefully you already created the partition. Then just follow these instructions.
Swap File
If you want to use a swap file, follow these instructions.
Note that if you are using btrfs, you’ll need to follow these instructions
and use the separate @swap
subvolume to ensure it’ll work correctly. Here’s
the commands to set up the swap file in btrfs:
# cd /swap
# touch swapfile
# chattr -m swapfile
# chattr +C swapfile
# btrfs property set swapfile compression none
Note that the chattr -m
command shouldn’t be necessary since it removes the
flag that disables compression and we want compression disabled, but it seems
you will get an “Invalid argument” error from chattr +C
if you don’t remove
it first (likely a bug).
Hibernation
Out of the box, you can use systemctl suspend
to suspend to RAM (aka
sleep/standby), but if you want to suspend to disk (aka hibernate), you’ll need
to set up hibernation. If you use a swap partition, it’s pretty easy to get
it set up since all you need to do is add the resume
kernel parameter (see
these instructions).
If you have an encrypted swap partition, be sure to point resume
to the
decrypted mount point or UUID.
If you use a swap file, it’ll be a bit more painful since you’ll need to
additionally provide the resume_offset
kernel parameter which will indicate
the offset in the disk that the file is at (see these instructions).
AUR
The Arch User Repository is a repository of PKGBUILD scripts that is maintained by various Arch Linux users. Unlike with packages that come from the official repositories, these PKGBUILD scripts are not maintained by trusted package maintainers meaning anyone can upload a package to the AUR and you must not blindly trust anything from the AUR. Despite this, the AUR is still very useful for packages that are not popular enough to be in the official repositories, so there are many users who regularly use packages built from the AUR. To this end, there are many AUR helpers that can make installing packages from the AUR convenient since usually you’d need to manually download the PKGBUILD file and any dependencies it needs, build the package, and then install the package. Doing this once in a while isn’t a big deal, but having to do it every time the package updates is a pain.
Of course, AUR helpers are not in the official repositories since they have the
exact same risks as anything else from the AUR. To install one, you’ll have to
manually build it. Follow these instructions
carefully to install your AUR helper of choice. There are many to choose from,
but nowadays I usually use yay
or paru
. Note that even if you use an
AUR helper, you should always strive to check the PKGBUILD and other files to
ensure there isn’t anything suspicious. Any decent AUR helper will make it
easier by showing you the diff every time the package updates.
VirtualBox Guest Additions
If you are installing in VirtualBox, you should install the VirtualBox Guest
Additions before you start trying to install any desktop environment or window
manager. This will provide the correct graphics drivers, without which you may
run into issues. Be sure to enable the systemd service so the kernel modules
get started correctly. For additional VirtualBox integration (shared clipboard,
seamless mode), ensure that VBoxClient-all
is set up to run upon login into
the desktop.
Window Manager
Assuming you don’t want to stay in the Linux Console all the time, you’ll want to install a desktop environment or window manager. Long story short, if you just want a standard graphical desktop experience that can be configured via a GUI and comes with some basic applications, then just install a desktop environment.
Of course, there are more than just these 4, but these are the ones that I’ve tried and are relatively popular. My personal choice would be Xfce since it is lightweight and not too ugly, but GNOME and KDE are definitely more fully featured.
However, nowadays I use i3 instead since I find its window tiling scheme makes a lot of sense and it still supports floating windows. It does take a while to set up and get used to, but I still like using it. Regardless, you are obviously free to choose whatever desktop environment or window manager you like, but if you do go with a window manager, this section may still be useful since most window managers require setting up similar things.
Before we go any further though, there are a few things you should know. First, there exists a Wayland equivalent of i3 called Sway. Wayland is quite usable now (though Sway doesn’t support Nvidia graphics cards), offers better security, and is aimed at modern-day use cases. However, the VirtualBox Guest Additions doesn’t support automatic display resizing with Wayland, so for now, I stick with i3.
Second, some desktop environments support using an alternative window manager, so if you like i3 (or any other window manager), but want a desktop experience that works out of the box, this is definitely an option to consider.
Installation
The i3
package group also includes
some basic packages that you will likely find useful, but you probably don’t
want everything in the group since some of the packages provide the same
functionality (and some of them even conflict with each other).
-
Window manager:
i3-wm
,i3-gaps
i3-wm
is the normal i3 window manager and technically the only thing you need to install to start using i3.i3-gaps
is a fork that puts aesthetic gaps between the windows. Of course, this is literally a waste of space, but it does look nice.
-
Status text:
i3status
,i3blocks
,i3status-rust
i3status
generates the status line at the bottom of the screen that presents the time, current network status, battery, etc.i3blocks
andi3status-rust
do the same, but support more functionality like click events and running arbitrary commands.i3status
prides itself on being very fast and honestly comes pretty close to having everything I want. However, I can’t deny the other options look nicer so I usually go withi3status-rust
.
-
Screen locker:
i3lock
,i3lock-color
,xscreensaver
,xsecurelock
Having a screen locker is not necessary for a VM, but for a physical machine, you’d definitely want one. The default one is
i3lock
which is pretty basic though still neat looking. However, it is missing somebasicnicer features like displaying the time.i3lock-color
fixes all that and is more customizable, though it does require installing via the AUR.xscreensaver
is a classic and comes with tons of weird graphical spectacles that’ll stress out your GPU and confuse your coworkers. Finally, there’sxsecurelock
which is heavily focused on security (e.g. preventing password bypassing, windows/notifications popping up), though if you actually want to keep your computer secure, encrypt the entire drive and shut it down or hibernate every time you leave it. Anyway, it’s honestly overkill for most people, but hey, it still supports showing the time unlikei3lock
, so this is the screen locker I go with.
Applications
You will likely want to install various applications since a bare bones i3 install has absolutely nothing which may be surprising for people used to other desktop environments or operating systems. I’d recommend installing at least a terminal emulator otherwise you will not be able to access a terminal inside i3 (if you forget to do this, you’ll need switch to another Linux Console to get access to a terminal).
-
Display manager:
xinit
,sddm
,lightdm
If you installed a full desktop environment, it probably included a display manager already so you should just use that. Otherwise, you have plenty of choices on how to start Xorg.
xinit
is the most manual one since it only provides thestartx
command which will start the desktop environment or window manager configured in~/.xinitrc
. As you may have guessed, you’ll still need to login via the Linux Console to runstartx
which isn’t very pretty. Also, if you frequently switch desktop environments or window managers, modifying a config file each time is annoying, so I’d recommend a proper display manager likesddm
orlightdm
. Either of them look nice enough out of the box, and unlike some other display managers, they are not specifically aimed at a certain desktop environment. Choose whatever suits your tastes, but I preferlightdm
with thelightdm-gtk-greeter
since it looks simple and doesn’t have too many dependencies.
-
Terminal emulator:
gnome-terminal
,xfce4-terminal
,terminator
,alacritty
,kitty
,cool-retro-term
There are tons of terminal emulators you can use, so I’m not going to even attempt to describe the different varieties, but here are some that I’ve personally used that work for me.
gnome-terminal
is a VTE-based terminal that is designed for the GNOME desktop environment, but it works well enough here (assuming you don’t mind all its dependencies). It does pretty much everything you’d expect from a modern terminal.xfce4-terminal
is another VTE-based terminal but this time intended for the Xfce desktop environment.terminator
is yet another VTE-based terminal that isn’t intended for any particular desktop environment and includes plenty of features.Nowadays, GPU accelerated terminals are all the rage (because obviously you need to be able to see text streaming at 144 fps), though I should warn you that if your hardware doesn’t have modern OpenGL support (e.g. VirtualBox), these may not work well.
alacritty
is the default for Sway, written in Rust (if that matters to you), and is the officially sanctioned replacement fortermite
(my previous chosen terminal).kitty
is another GPU accelerated terminal that offers a lot of flexibility with a variety of plugins. Finally,cool-retro-term
is a fun terminal that lets you time travel to the past when screen burn-in was a thing and everything was monochrome.
-
Application launcher:
dmenu
,rofi
dmenu
is the default application launcher and it works perfectly fine even though it is a bit lacking in features. Out of the box, it will include terminal programs as well which I find annoying since I would’ve opened up a terminal if I wanted one of those. You can use the includedi3-dmenu-desktop
script to instead only show programs with a desktop entry. An alternative application launcher isrofi
which has some more features like showing icons, supporting themes, and switching applications (its original purpose). Other than those, there are plenty of alternative application launchers so choose what you like. I personally go withrofi
since it has icons.
-
Font:
noto-fonts
,ttf-dejavu
,ttf-hack
,terminus-font
,gohufont
Not sure if I should bother having this section since font preference is almost purely personal taste, but here we go anyway.
To ensure you have decent coverage, you’ll want to start with a font that provides a base font set.
ttf-dejavu
is an extension of Bitstream Vera intended to provide more Unicode coverage. It also includes a decent monospace font with some thought paid to programming. Alternatively,noto-fonts
is a Google commissioned font that intends to cover all of Unicode so there will be “no more tofu”. If you install its additional packages, you’ll really get almost full coverage, but it will take up a lot of space.ttf-hack
is a nice monospace font that is derived from Bitstream Vera and DejaVu, but includes some more programming specific adjustments. If you prefer a bitmap font, you can try outterminus-font
(the same font asLat2-Terminus16
in the Linux Console) orgohufont
from the AUR. However, bitmap fonts are falling out of favor so you may have to struggle to get them to work.Regardless of which font you pick, you may need to do some font configuration to get things working properly.
-
Notification server:
dunst
Without a notification server, you won’t be able to see any notifications.
dunst
is a lightweight notification server that allows some basic appearance customization, notification history, and even scripting based on the incoming notifications. You can also use notification servers specifically intended for a desktop environment, but I find thatdunst
gets the job done well enough.
Backup Kernel
Since Arch has a rolling release model, packages are upgraded promptly after the upstream source is. Though packages generally go through the testing repository first, the chances of something breaking are still higher than usual. This can especially be troublesome if a kernel upgrade breaks your system since generally you won’t be able to boot anymore, and you’ll have to resort to booting a live installation in order to fix things.
With this in mind, I’d recommend also installing the longterm release kernel.
This kernel will still receive bug fixes and security updates, but not any new
features present in the latest stable version. For Arch, you can install it via
the linux-lts
package. Note that this package runs the latest longterm
release, so it still gets upgraded whenever a new longterm release is chosen
(approximately once a year).
Once you’ve installed the linux-lts
package, you’ll need to set up your boot
loader to have additional entries for the linux-lts
kernel. By default, the
mkinitcpio
hook should create new vmlinuz-linux-lts
and
initramfs-linux-lts
files (as well as fallback versions) that you can refer
to in the boot loader entry. GRUB’s grub-mkconfig
will actually detect the
additional kernel versions for you.
Note that using btrfs mitigates the need to keep a backup kernel (assuming your kernel is stored on the btrfs file system of course) since you can revert to an older version if something breaks. However, you may still want to keep a backup kernel anyway since you might not even be able to boot using the broken kernel.
Firewall
Linux doesn’t exactly need a firewall since ports are closed by default, but if
you’d like to be a bit safer, I’d still recommend having at least a basic one
set up. This is especially true if you run any services that accept incoming
connections (ssh, Samba) or your system is exposed on the public internet.
Though you can manage nftables
manually, I find that using ufw works
pretty well and is much simpler. It generally has acceptable defaults, but
you’ll need to add exceptions for any services you wish to expose. If you can
only access your system remotely, be sure to set up the exception for ssh
carefully otherwise you may lock yourself out.
Hardware
If you are not installing in a virtual machine, you’ll likely need to look at these additional guides to set up your specific hardware:
Regular Maintenance
Congratulations! Your Arch Linux system is fully set up and ready for use (well, according to my standards at least). If you are new to Arch, you should read through the system maintenance guide. To sum it up, the main thing you need to do is keep your system up-to-date on a regular basis with these steps:
- Check archlinux.org for any required manual intervention
- Run
pacman -Syu
- Deal with any
pacnew
orpacsave
files - Reboot
- Confirm all your systemd services are working with
systemctl status
Don’t put this off since having to deal with multiple changes requiring manual intervention can be a pain and puts your system at higher risk of being permanently broken. Also, only do an upgrade when you can accept your system being broken for some time (e.g. don’t upgrade right before an important presentation).
Conclusion
Hopefully you got what you needed out of this guide. Though Arch can be a pain to set up, many Arch users enjoy having a system that they “built” themselves4. Whether you decide to join us or not, hopefully you found this experience valuable.
-
You may be thinking that the Linux console previously had scrollback capabilities by itself. Don’t worry, you’re not crazy. It was removed somewhat recently. Actually, it’s possible by the time you are reading this, it was restored back already in which case maybe
tmux
will be less useful. ↩ ↩2 -
The ArchWiki’s entry on partitioning describes these reasons in more detail, but in general, there’s little reason to use MBR unless you are stuck with legacy hardware. ↩
-
This attack vector is known as the Evil Maid Attack. The correct way to prevent this is to use Secure Boot and locking down your BIOS, but in my opinion, that is overkill unless you are worried about an intelligence agency coming for you. ↩
-
Actually, if you want the real “build-it-yourself” experience, you should consider trying out Gentoo or LFS (Linux From Scratch). I personally have not tried either of them, but my initial impressions are that they aren’t worth the hassle. They do offer more customizability than Arch since they require you to compile everything from source, but that doesn’t seem that useful unless you are trying to micro-optimize for your hardware, using an unusual CPU architecture, or want to experience truly building a Linux system yourself. ↩