Most Arch install guides read like someone dumped their terminal history into a blog and called it a day. I wanted more than that.
I wanted a system that was secure, fast, and didn’t ask me for a password every time I booted. I wanted TPM2-backed full-disk encryption, a modern boot process with UKI, and a layout that respected my time. And I wanted it to be repeatable — no more tinkering for hours every six months.
I wrote a script to make that possible. It’s called archtpm-install.sh
.
It works well enough to trust. It’s not perfect. But it got me over the line — and it might help you too.
⚠️ Not Production-Ready
This script is a personal experiment. It worked for me — once — and then I kept tweaking it.
It is not production-grade. It assumes a lot. It wipes your disk. It doesn’t ask for confirmation. And parts of it — especially the START_STAGE
feature — are completely untested.
There is no warranty, no guarantee it won’t destroy your data, and no promise it will behave the same way twice.
If you run it, you’re taking full responsibility. Please read it line by line, understand what it does, and adapt it for your own setup.
You’ve been warned.
The Diagram
Here’s how it all ties together:

This isn’t just a boot sequence. It’s a system of trust. From power-on to decrypted root, each step confirms the last — hardware, firmware, bootloader, kernel, unlock.
Why systemd-boot Instead of GRUB?
GRUB tries to support everything. And that’s kind of the problem.
In contrast, systemd-boot
is:
- Simpler — just drops UKIs into the EFI partition and lists them
- Faster — no
grub-mkconfig
, no scanning partitions or OSes - Predictable — it’s just a boot menu for
.efi
files
GRUB is powerful, but most of that power comes with complexity I don’t need. Kernel updates don’t require touching a config. Just rebuild the UKI, and you’re done.
I didn’t switch to systemd-boot because I hate GRUB. I switched because I wanted to understand my boot process — and own it.
Why Dracut over mkinitcpio?
Arch uses mkinitcpio
by default — and it’s good. But dracut
is what Fedora, RHEL, Gentoo, and Debian use. It’s:
- More modular — builds your initrd from systemd-style config
- UKI-native — supports bundling directly into unified kernel images
- Less magic — no hooks, just config
In this setup, dracut
builds a self-contained UKI file that includes:
- The initramfs
- The kernel
- The kernel command line
- An embedded splash image (optional)
You just copy that one file into /boot/efi/EFI/Linux/
, and systemd-boot loads it directly.
mkinitcpio vs dracut: What’s the Difference?
Feature | mkinitcpio | dracut |
---|---|---|
Config Style | Bash-based hooks | systemd-style .conf files |
UKI Support | Requires manual steps | Native UKI generation |
Modularity | Less modular | Highly modular |
Package Usage | Default in Arch Linux | Default in Fedora, RHEL, Debian |
Ease of Debug | Familiar to Arch users | More verbose logs, dependency-based |
Snapshot-aware | No | Partial (via systemd integration) |
Bootloader Hooks | Manual | Integrated with systemd-boot /UKI |
TL;DR: If you’re using UKIs with systemd-boot, dracut just works — no duct tape, no guessing.
A Quick Word on TPM2
When you enrol your LUKS volume with systemd-cryptenroll --tpm2
, you’re telling the system: only decrypt this if the environment matches.
That includes:
- The kernel image
- Secure Boot state (if enabled)
- PCR values (measured boot)
- The TPM’s internal secrets
This isn’t just a stored passphrase. It’s a sealed secret — bound to your system’s identity and boot sequence.
It’s secure, fast, and invisible when it works.
Is the UKI Encrypted?
No — and that’s by design.
The UKI lives on the EFI System Partition (ESP), which has to stay unencrypted so the firmware can read it and begin the boot process.
It contains:
- A UEFI boot stub (
systemd-stub
) - The kernel
- The initrd (built by
dracut
) - The kernel command line
You can think of it like a hotel room safe: there’s a printed label on the door that says, “Enter your PIN and turn the knob.”
That label is public. But it doesn’t help unless you know the code.
The UKI works the same way. It tells the system how to boot, but it can’t actually boot unless the TPM agrees — unless the system proves it’s genuine, untampered, and running on the right hardware.
Anyone can read the UKI. But without the right key — sealed inside the TPM — your root stays locked tight.
Why Btrfs?
I used to think Btrfs was overkill. But once you get used to it, it’s hard to go back.
Strengths
- Subvolumes: Mount
/home
,/var
,/opt
, etc. separately — without separate partitions. - Snapshots: Roll back from a bad
pacman -Syu
in seconds. - Space-efficient: Snapshots are copy-on-write. Fast, cheap, reliable.
- No fsck: It self-heals with checksums. No surprise boot-time scans.
- Compression (if enabled): Save disk space on logs and source code.
Cons
- Not a drop-in replacement for ext4: You need to understand subvolume layout.
- Bootloader integration: You can’t boot from encrypted Btrfs without an initramfs.
- Still maturing in edge cases: RAID5/6 is still experimental.
- Debugging is more complex: Especially with layered subvolume mount points.
In this setup, Btrfs was worth it. I could snapshot before risky upgrades. Roll back if a dracut rebuild went sideways. And I never had to repartition to separate state from logs.
What the Script Does
I wrote archtpm-install.sh
to automate this setup — not to hide the details, but to make the process reliable and repeatable.
Here’s what it actually does, broken into two clear stages:
Part 1: Disk Setup and Encryption
Wipes your disk (seriously — be careful)
Partitions for EFI and LUKS-encrypted Btrfs
Sets up TPM2-based unlocking with
systemd-cryptenroll
Mounts a structured set of Btrfs subvolumes:
@ → / @home → /home @var → /var @opt → /opt @tmp → /tmp @.snapshots → /.snapshots @nix → /nix
Part 2: Installing Arch and Boot Configuration
- Installs Arch with
pacstrap
, configures locale, users, time - Installs
dracut
and sets up a UKI build - Boots with
systemd-boot
, no GRUB
It’s minimal. It’s opinionated. But it works.
Try It (If You Dare)
Boot into an Arch ISO, then run:
curl -sL <https://gist.githubusercontent.com/oliverdaff/c3c037b0509ba9d961c8c1039a70706e/raw/archtpm-install.sh> | bash
Please: READ THE SCRIPT FIRST. Change the variables at the top. Know what it’s doing.
You don’t want to learn about cryptsetup
from the other side of dd if=/dev/zero
.
What Comes After
Once I had the base working, I layered on:
- i3 — lightweight, keyboard-driven window manager
- Nix + Home Manager — to declaratively manage system config, packages, and dotfiles
- tmux — for persistent, multiplexed terminal workflows
- Neovim — as my full-time editor, tuned just the way I like it
Everything’s reproducible from a single Git repo. I can reinstall Arch, decrypt the disk, and be back in my working environment in under 30 minutes — tiling windows, terminal sessions, and all.
The script gave me a clean base. This stack made it mine.
How it all fits together — boot to browser, terminal to tags — is a story for another day.
Final Words
This setup boots in seconds. It unlocks itself. It snapshots. It rolls back. And I can reinstall it in under 20 minutes.
It’s not for everyone. But if you’ve been fighting Arch installs and want a repeatable way to build a secure, modern Linux system — this might help.
I didn’t write this script to automate everything. I wrote it to restore trust — in my tools, my machine, and how I boot.