Combining OverlayFS with a Btrfs layout on Debian Forky unlocks powerful advantages that Btrfs subvolumes and snapshots cannot achieve alone. While Btrfs handles structural versioning, snapshots, and data safety at the block/filesystem level, OverlayFS operates at the VFS layer to handle dynamic, temporary, or isolated runtime modifications.
One more option provided is recovery main instance via booting into Overlay instance using Grub Submenu. By explicitly mounting the top-level Btrfs volume (subvolid=5) into a temporary directory like /mnt, you step outside the overlay's jurisdiction. This allows the kernel to recognize the true Btrfs layout and perform instant atomic subvolume swaps.
sudo mount -o subvolid=5 /dev/vda4 /mnt
sudo btrfs subvolume list /mnt/@
sudo mv /mnt/@ /mnt/@_broken
sudo btrfs subvolume snapshot /mnt/@snapshots/required-ID/snapshot /mnt/@
sudo btrfs subvolume delete /mnt/@_broken
Final instance btrfs/xfs layout
boris@Debian1510:~$ hostnamectl
Static hostname: Debian1510
Icon name: computer-vm
Chassis: vm 💽
Machine ID: edf88060aa784d0f9b7f14b3c6d1a8c1
Boot ID: e2264038aeb4455f99e854dab9d16b17
Virtualization: kvm
Operating System: Debian GNU/Linux forky/sid
Kernel: Linux 7.2.9+deb14-amd64
Architecture: x86-64
Hardware Vendor: QEMU
Hardware Model: Standard PC _Q35 + ICH9, 2009_
Hardware Version: pc-q35-11.1
Firmware Version: edk2-20260812-9.fc45
Firmware Date: Wed 2026-08-12
Firmware Age: 2month 3d
boris@Debian1510:~$ findmnt -t btrfs
TARGET SOURCE FSTYPE OPTIONS
/ /dev/vda4[/@] btrfs rw,noatime,compress=zstd:3,discard=async,space_cache=v2,subvolid=257,subvol=/@
├─/.snapshots /dev/vda4[/@snapshots] btrfs rw,noatime,compress=zstd:3,discard=async,space_cache=v2,subvolid=258,subvol=/@snapshots
├─/home /dev/vda4[/@home] btrfs rw,noatime,compress=zstd:3,discard=async,space_cache=v2,subvolid=259,subvol=/@home
├─/var/cache /dev/vda4[/@cache] btrfs rw,noatime,compress=zstd:3,discard=async,space_cache=v2,subvolid=260,subvol=/@cache
└─/var/log /dev/vda4[/@log] btrfs rw,noatime,compress=zstd:3,discard=async,space_cache=v2,subvolid=261,subvol=/@log
boris@Debian1510:~$ lsblk -f
NAME FSTYPE FSVER LABEL UUID FSAVAIL FSUSE% MOUNTPOINTS
sr0
vda
├─vda1 vfat FAT32 D643-B66B 68.2M 12% /boot/efi
├─vda2 ext4 1.0 c8860b5b-e657-4ff2-acdb-e2a08947a7b5 1.6G 3% /boot
├─vda3 xfs 41565303-cab9-4cb6-9f9c-5ec5d8acbc0e 42.9G 2% /opt
└─vda4 btrfs 75028dc8-40ef-4c97-8944-d8850c1ee107 42.8G 13% /var/log
/var/cache
/home
/.snapshots
/
###################################################
On clean Debian forky KVM Guest proceed as follows
###################################################
sudo apt install inotify-tools gawk git build-essential snapper -y
1.Switch @rootfs to @ ( standard names convention)
mkdir -p /mnt/btrfs_root
mount -o subvolid=5 /dev/vda4 /mnt/btrfs_root
mkdir -p /mnt/btrfs_root/btrfs_base
btrfs subvolume snapshot /mnt/btrfs_root/@rootfs /mnt/btrfs_root/btrfs_base/@
mv /mnt/btrfs_root/btrfs_base/@ /mnt/btrfs_root/@
rmdir /mnt/btrfs_root/btrfs_base
umount /mnt/btrfs_root
mkdir -p /mnt/system-root
mount -o subvol=@ /dev/vda4 /mnt/system-root
mount /dev/vda2 /mnt/system-root/boot
mount /dev/vda1 /mnt/system-root/boot/efi
for i in /dev /dev/pts /proc /sys /run; do mount -B $i /mnt/system-root$i; done
##########
Next step
##########
chroot /mnt/system-root /bin/bash
grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=debian --recheck
grub-install --target=x86_64-efi --efi-directory=/boot/efi --removable
update-initramfs -u -k all
update-grub
exit
#########################
Upon exiting from chroot
#########################
for i in /run /sys /proc /dev/pts /dev; do umount /mnt/system-root$i; done
umount /mnt/system-root/boot/efi
umount /mnt/system-root/boot
sed -i 's/rootflags=subvol=@rootfs/rootflags=subvol=@/g' /boot/grub/grub.cfg
#############################################
Update /mnt/system-root/etc/fstab as follows
#############################################
Remove old entry and replace with
UUID=75028dc8-40ef-4c97-8944-d8850c1ee107 / btrfs defaults,subvol=@,compress=zstd,noatime 0 1
:wq
########
systemctl daemon-reload
mount -a
##########
System reboot
#######################################################
Log into instance back and create subvolumes per standard schema
#######################################################
findmnt -t btrfs
update-grub
mkdir -p /mnt/btrfs_base
mount -o subvolid=5 /dev/vda4 /mnt/btrfs_base
btrfs subvolume create /mnt/btrfs_base/@snapshots
btrfs subvolume create /mnt/btrfs_base/@home
btrfs subvolume create /mnt/btrfs_base/@cache
btrfs subvolume create /mnt/btrfs_base/@log
###########
Next step
###########
snapper -c root create-config /
btrfs subvolume delete /.snapshots
mkdir /.snapshots
##########################
Backup user's home folder
##########################
tar -czf boris.tar.gz boris
cp boris.tar.gz /tmp
btrfs subvolume list /
###############################
Update /etc/fstab as follows
###############################
UUID=75028dc8-40ef-4c97-8944-d8850c1ee107 / btrfs defaults,subvol=@,compress=zstd,noatime 0 1
UUID=75028dc8-40ef-4c97-8944-d8850c1ee107 /home btrfs defaults,subvol=@home,compress=zstd,noatime 0 1
UUID=75028dc8-40ef-4c97-8944-d8850c1ee107 /var/cache btrfs defaults,subvol=@cache,compress=zstd,noatime 0 1
UUID=75028dc8-40ef-4c97-8944-d8850c1ee107 /var/log btrfs defaults,subvol=@log,compress=zstd,noatime 0 1
UUID=75028dc8-40ef-4c97-8944-d8850c1ee107 /.snapshots btrfs subvol=@snapshots,compress=zstd,noatime 0 0
# /boot was on /dev/vda2 during installation
UUID=c8860b5b-e657-4ff2-acdb-e2a08947a7b5 /boot ext4 defaults 0 2
# /boot/efi was on /dev/vda1 during installation
UUID=D643-B66B /boot/efi vfat umask=0077 0 1
# /opt was on /dev/vda3 during installation
UUID=41565303-cab9-4cb6-9f9c-5ec5d8acbc0e /opt xfs defaults 0 0
/dev/sr0 /media/cdrom0 udf,iso9660 user,noauto 0 0
:wq
##########################
/etc/fstab verification
##########################
systemctl daemon-reload
mount -a
##########################
findmnt -t btrfs
cd /home
cp /tmp/*.tar.gz .
tar -xzf boris.tar.gz
#################
sudo chmod 750 /.snapshots
sudo umount /mnt/btrfs_base
sudo snapper -c root create --description "First baseline snapshot"
#################
System reboot
#################
$ sudo apt update
$ sudo apt install inotify-tools gawk git build-essential -y
$ git clone https://github.com/Antynea/grub-btrfs.git
$ cd grub-btrfs
$ sudo make install
###########################################
Make sure grub-btrfsd.service is correct
###########################################
$ sudo systemctl edit --full grub-btrfsd.service
$ sudo systemctl daemon-reload
$ sudo systemctl enable --now grub-btrfsd.service
$ sudo update-grub
$ sudo reboot
############ Overlay Setup ############
We need to swap out Debian's default initramfs-tools and replace it with Dracut, which natively understands the Fedora-style live overlay parameters.
$ sudo apt update
$ sudo apt install dracut dracut-core -y
########################################
Inject the working parameters exclusively into the Snapshot Configuration
$ sudo nano /etc/default/grub-btrfs/config
GRUB_BTRFS_SNAPSHOT_KERNEL_PARAMETERS="'rd.live.overlay.overlayfs=1 rw'"
########################################
Force Dracut to re-build your active kernel images with overlay modules enabled
########################################
$ echo 'add_dracutmodules+=" overlayfs "' | sudo tee /etc/dracut.conf.d/overlayfs.conf
$ sudo dracut -H --hostonly-mode=sloppy --add overlayfs --force
$ sudo /etc/grub.d/41_snapshots-btrfs
#######################################
Finalize and update your master GRUB boot menu layout
$ sudo update-grub
#######################################
Overlay instance layout
############################
boris@Debian1510:~$ hostnamectl
Static hostname: Debian1510
Icon name: computer-vm
Chassis: vm 💽
Machine ID: edf88060aa784d0f9b7f14b3c6d1a8c1
Boot ID: 8874785955e746679ce2d24ae4e5a257
Virtualization: kvm
Operating System: Debian GNU/Linux forky/sid
Kernel: Linux 7.2.9+deb14-amd64
Architecture: x86-64
Hardware Vendor: QEMU
Hardware Model: Standard PC _Q35 + ICH9, 2009_
Hardware Version: pc-q35-11.1
Firmware Version: edk2-20260812-9.fc45
Firmware Date: Wed 2026-08-12
Firmware Age: 2month 3d
boris@Debian1510:~$ findmnt -t btrfs
TARGET SOURCE FSTYPE OPTIONS
/run/rootfsbase /dev/vda4[/@snapshots/14/snapshot]
btrfs ro,noatime,compress=zstd:3,discard=async,space_cache=v2,subvolid=276,subvol=/@snapshots/14/sn
/.snapshots /dev/vda4[/@snapshots] btrfs rw,noatime,compress=zstd:3,discard=async,space_cache=v2,subvolid=258,subvol=/@snapshots
/home /dev/vda4[/@home] btrfs rw,noatime,compress=zstd:3,discard=async,space_cache=v2,subvolid=259,subvol=/@home
/var/cache /dev/vda4[/@cache] btrfs rw,noatime,compress=zstd:3,discard=async,space_cache=v2,subvolid=260,subvol=/@cache
/var/log /dev/vda4[/@log] btrfs rw,noatime,compress=zstd:3,discard=async,space_cache=v2,subvolid=261,subvol=/@log
boris@Debian1510:~$ mount|grep 'on / '
LiveOS_rootfs on / type overlay (rw,relatime,lowerdir=/run/rootfsbase,upperdir=/run/overlayfs,workdir=/run/ovlwork,uuid=on)
boris@Debian1510:~$ lsblk -f
NAME FSTYPE FSVER LABEL UUID FSAVAIL FSUSE% MOUNTPOINTS
sr0
vda
├─vda1 vfat FAT32 D643-B66B 68.2M 12% /boot/efi
├─vda2 ext4 1.0 c8860b5b-e657-4ff2-acdb-e2a08947a7b5 1.6G 3% /boot
├─vda3 xfs 41565303-cab9-4cb6-9f9c-5ec5d8acbc0e 42.9G 2% /opt
└─vda4 btrfs 75028dc8-40ef-4c97-8944-d8850c1ee107 42.8G 13% /var/log
/var/cache
/home
/.snapshots
/run/rootfsbase






