Skip to content

Instantly share code, notes, and snippets.

@clayadavis
Last active April 30, 2025 22:12
Show Gist options
  • Save clayadavis/d1c0530bb8a703df8e8266f51235fdf6 to your computer and use it in GitHub Desktop.
Save clayadavis/d1c0530bb8a703df8e8266f51235fdf6 to your computer and use it in GitHub Desktop.
Installing Ubuntu Server 24.04 with BTRFS

Install Ubuntu Server

Custom storage layout

We want to have a separate ext4 boot partition because Ubuntu's grub doesn't really like booting from btrfs. So we have something like

MOUNT POINT  SIZE  TYPE
/            474G  new btrfs
/boot          2G  new ext4
/boot/efi      1G  existing vfat

After install, before reboot

At the end of install, when you are prompted to view the full log or reboot, press Ctrl + Alt + F2 to open a shell.

Unmount everything with

sudo umount -a

Mount the root partition with

sudo mount /dev/<sdaX|nvme0n1pX> /mnt

Copy resolv.conf

sudo cp -vf /etc/resolv.conf /mnt/etc/resolv.conf

Remove swapfile

sudo rm /mnt/swap.img

Snapshot root, thereby creating a root level subvolume

sudo btrfs su snapshot /mnt/ /mnt/@

Remove the main installed contents

sudo rm -r /mnt/{bin,bin*,boot,cdrom,etc,home,lib,lib*,media,mnt,opt,root,run,sbin,sbin*,snap,srv,sys,tmp,usr,var}

Create the rest of the subvolumes

sudo btrfs su create /mnt/@{home,var,tmp,snapshots,swap}

Move var to its own subvolume

sudo mv /mnt/@/var/* /mnt/@var

Unmount the root partition

sudo umount /mnt

Remount and Chroot

Mount the subvolumes as follows:

sudo mount -o subvol=@ /dev/<sdaX|nvme0n1pX> /mnt
sudo mount -o subvol=@home /dev/<sdaX|nvme0n1pX> /mnt/home
sudo mount -o subvol=@tmp /dev/<sdaX|nvme0n1pX> /mnt/tmp
sudo mount -o subvol=@var /dev/<sdaX|nvme0n1pX> /mnt/var
sudo mkdir /mnt/.snapshots
sudo mount -o subvol=@snapshots /dev/<sdaX|nvme0n1pX> /mnt/.snapshots
sudo mkdir /mnt/swap
sudo mount -o subvol=@swap /dev/<sdaX|nvme0n1pX> /mnt/swap

Mount boot partitions

sudo mount /dev/<sdaY|nvme0n1pY> /mnt/boot
sudo mount /dev/<sdaZ|nvme0n1pZ> /mnt/boot/efi

Mount dev, proc, sys, and run in preparation for chroot

for d in dev proc sys run; do sudo mount --rbind /$d /mnt/$d; done

Chroot into the created environment

sudo chroot /mnt /bin/bash

GRUB, swap, and fstab

Because we are using subvolumes with btrfs we need to regenerate the grub configuration file and update the fstab file. First, regenerate the grub configuration file.

sudo grub-mkconfig -o /boot/efi/EFI/ubuntu/grub.cfg
sudo update-grub

Create the swapfile

btrfs filesystem mkswapfile --size 4g --uuid clear /swap/swapfile

Next, update the fstab with sudo vim /etc/fstab to look like this for each subvolume

/dev/<sdaX|nvme0n1pX> /   btrfs   ssd,noatime,space_cache=v2,compress=lzo,discard=async,subvol=@  0 0

Change the last line for the swapfile to look like this: /swap/swapfile none swap defaults 0 0

Reboot, update, and install snapper

c.f. https://medium.com/@inatagan/installing-debian-with-btrfs-snapper-backups-and-grub-btrfs-27212644175f#aa3c

Update everything

sudo apt update && sudo apt upgrade -y

Install snapper

sudo apt install snapper

We need to make some prep-work to set snapper to save our snapshots to the subvolume @snapshots that we created previously.

cd /
sudo umount .snapshots
sudo rm -r .snapshots

Now we can create a new configuration for Snapper with:

sudo snapper -c root create-config /

Remove the auto-created subvolume, recreate the directory, and remount @snapshots

sudo btrfs subvolume delete /.snapshots
sudo mkdir /.snapshots
sudo mount -av

Add the sudo group to allow users to use snapper:

sudo snapper -c root set-config 'ALLOW_GROUPS=sudo'
sudo snapper -c root set-config 'SYNC_ACL=yes'

Use snapper to create a snapshot

Create our first snapshot

sudo snapper -c root create --description "default fresh install"

List the snapshots

sudo snapper ls

To make a rollback use the command

sudo snapper --ambit classic rollback <snapshot_number>
sudo reboot
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment