Ubuntu 23.10 with ZFS on root and ZFSBootMenu
This post describes how I install Ubuntu 23.10 with ZFS on root, booting through ZFSBootMenu (ZBM), using a script that automates the steps from the ZBM guide with a few changes of my own. I tested it with Ubuntu 23.04 and 23.10.
Written for Ubuntu 23.10 in December 2023. Ubuntu 23.10 reached end of life in July 2024; the steps are untested on later releases.
Why I moved to ZFSBootMenu
I recently had to reinstall my laptop and a few virtual machines. I had tested BTRFS earlier, but it gave me too many issues, so I went back to ZFS, which I have used for years.
I used to install my Ubuntu machines by following the OpenZFS guide. It is long, and it covered only the latest LTS release, while I run 23.10.
Two of my laptops also stopped booting through GRUB into their ZFS-on-root Ubuntu within the same month. I moved to ZFSBootMenu as the boot loader. Because I multiboot, I put rEFInd in front of it for a graphical boot menu.
The ZBM guide and where I differ
The ZBM install differs from the OpenZFS one mainly in using a single dataset. I do not repeat its steps here; they are on the ZFSBootMenu website.
I made five changes. The ZBM guide creates only an EFI partition and a ZFS partition, and I add a swap partition. My main laptop has an RTL8821CE wifi card with faulty default drivers, which needs extra steps. I often test on virtual machines, so I wrote a script to automate the installation. All my machines use ZFS native encryption, so everything in the script is built around it. Finally, I use rEFInd because it is simple to configure and gives a clear graphical menu.
What the script does
The script automates every step of the ZBM guide, so instead of repeating the ZBM documentation line by line I describe what the script does. It opens with variables to set before launching:
########################
# Change ${RUN} to true to execute the script
RUN="false"
# Variables - Populate/tweak this before launching the script
export DISTRO="desktop" # server, desktop
export RELEASE="mantic" # The short name of the release as it appears in the repository (mantic, jammy, etc)
export DISK="sda" # Enter the disk name only (sda, sdb, nvme1, etc)
export PASSPHRASE="SomeRandomKey" # Encryption passphrase for "${POOLNAME}"
export PASSWORD="mypassword" # temporary root password & password for ${USERNAME}
export HOSTNAME="myhost" # hostname of the new machine
export USERNAME="myuser" # user to create in the new machine
export MOUNTPOINT="/mnt" # debootstrap target location
export LOCALE="en_US.UTF-8" # New install language setting.
export TIMEZONE="Europe/Rome" # New install timezone setting.
export RTL8821CE="false" # Download and install RTL8821CE drivers as the default ones are faulty
## Auto-reboot at the end of installation? (true/false)
REBOOT="false"
###########################################################################
# Enable/disable debug. Only used during the development phase.
DEBUG="false"
Each one is commented in the script and should be self-explanatory.
The PASSWORD and PASSPHRASE variables are in plain text, so, in theory, they pose a security risk. You are exposed to this risk only during the installation while in front of your computer. Once the installation is completed and you reboot the machine, these files are gone as they only live at runtime when you boot from your USB key (see GitHub for all the installation steps)
Set the variables, then run the script as root. It does the following, in order:
- Sets the swap partition size equal to your physical memory, in case you enable hibernation later.
- Initialises and partitions the disk you selected.
- Creates the ZFS pool.
- Runs debootstrap to install the base system on the target disk.
- Initialises the swap partition, encrypted.
- Installs ZBM and adds it to the EFI menu. This is redundant, since rEFInd follows, but I want a fallback.
- Installs rEFInd and its default dark theme.
- Creates the required groups and the basic network configuration.
- Creates your user.
- Installs the Ubuntu flavour you selected (server or desktop).
- Disables log compression, because the ZFS pool already compresses.
- Downloads and installs the RTL8821CE drivers, if selected.
- Reboots, if enabled. Otherwise you reboot manually.
The result is a ZFS-on-root Ubuntu system.