setup-btrfs.sh hilft dabei, einen Debian-, Ubuntu- oder anderen Debian-basierten Server mit einer einzelnen Btrfs-Root-Partition in ein System mit sauberer Subvolume-Struktur zu verwandeln – geeignet für Timeshift und Container-Workloads. Funktioniert sowohl beim einmaligen Umstieg auf einer frischen Installation als auch nachträglich auf einem bereits laufenden, migrierten System, um dort noch fehlende Subvolumes zu ergänzen (kein Neustart nötig).
Auf einem Debian- (oder Debian-basierten) System mit Btrfs-Root führt das Skript im Wesentlichen aus:
-
Ermittelt das aktuelle Root-Device per
findmnt(z. B./dev/vda2[/@rootfs]→/dev/vda2). -
Mountet das Btrfs-Top-Level (
subvolid=5) nach/mnt/btrfs-root. -
Prüft vorab den freien Speicherplatz (jedes Byte auf
/wird während der Migration kurzzeitig dupliziert) und bricht ab, wenn es eng wird. -
Erkennt eine schon (teilweise) durchgeführte Migration und wechselt automatisch in einen inkrementellen Modus: Läuft
/bereits von einem benannten Subvolume, werden Root, GRUB und das Default-Subvolume nicht mehr angefasst — es werden nur noch fehlende Subvolumes für noch nicht separat gemountete Pfade ergänzt, sofort aktiv, ohne Neustart. Jeder Zielpfad wird einzeln klassifiziert: bereits korrekt eingerichtet (übersprungen, taucht im Auswahldialog gar nicht erst auf), anderweitig belegt (übersprungen mit Warnung, wird nicht überschrieben), oder noch offen (Kandidat für die Auswahl). -
Fragt in einem interaktiven Terminal ausdrücklich nach ("ja" eintippen), bevor irgendetwas verändert wird — samt Warnhinweis, was das Skript tut und dass ein Fehlschlag das System unbootbar machen kann. Ohne Terminal (automatisierte Läufe) wird die Abfrage übersprungen.
-
Zeigt in einem interaktiven Terminal einen Auswahldialog (
whiptail): universell sinnvolle Subvolumes (@root,@home,@log,@cache,@tmp_var,@tmp) sind vorausgewählt, alle vom Software-Stack abhängigen (Datenbanken, Docker/Podman, Webserver-Docroot) starten abgewählt — beides frei änderbar. Abgewählte Pfade bekommen kein eigenes Subvolume und bleiben einfach Teil von@. Ohne interaktives Terminal (z.B. bei automatisierter Ausführung) werden nur die universell sinnvollen Subvolumes ohne Nachfrage angelegt. -
Stoppt bekannte Dienste (
mongod,mysql,postgresql,docker) vor deren Datenkopie, falls sie gerade laufen, und startet sie danach wieder — für eine konsistente Kopie statt halbgeschriebener Dateien. -
Legt (idempotent) folgende Subvolumes an:
@(neues Root)@root@home@spool@log@cache@tmp_var@srv@tmp@opt@containers@docker@mongodb@mysql@postgresql@docker-volumes@containers-volumes@www
-
Kopiert das aktuelle Root-Dateisystem nach
@(mit Ausschlüssen für/dev,/proc,/sys,/run,/mnt,/media,/lost+foundsowie – automatisch aus dem Mapping unten abgeleitet – allen Pfaden, die ein eigenes Subvolume bekommen). -
Kopiert die Inhalte wichtiger Verzeichnisse in ihre Subvolumes:
/root→@root/home→@home/var/spool→@spool/var/log→@log/var/cache→@cache/var/tmp→@tmp_var/srv→@srv/tmp→@tmp/opt→@opt/var/lib/containers→@containers/var/lib/docker→@docker/var/lib/mongodb→@mongodb/var/lib/mysql→@mysql/var/lib/postgresql→@postgresql/var/lib/docker/volumes→@docker-volumes/var/lib/containers/storage/volumes→@containers-volumes/var/www→@www
Datenbank-Subvolumes (
@mongodb,@mysql,@postgresql) sowie die benannten Docker-/Podman-Volumes (@docker-volumes,@containers-volumes) werden mitnodatacowstattcompress=zstd/autodefraggemountet – Copy-on-Write und Kompression vertragen sich schlecht mit dem Random-Write-Verhalten von Datenbanken und beliebigen Volume-Workloads. Image-Layer und Metadaten in@docker/@containersselbst bleiben davon unberührt und weiterhin komprimiert. -
Bereitet im neuen Root (
@) die Mountpoints vor, damit die Subvolumes dort eingehängt werden können. -
Passt
/etc/fstabim laufenden System an:- legt ein Backup als
fstab.backup-YYYY-MM-DD-HHMMSSan, - kommentiert alte Btrfs-Root-Zeilen als
#OLD-ROOT …aus, - fügt neue Btrfs-Einträge für
/,/home,/var/log,/var/lib/docker,/var/wwwusw. mit den entsprechenden@…-Subvolumes hinzu.
- legt ein Backup als
-
Passt GRUB an (falls vorhanden):
- ersetzt ggf.
@rootfsdurch@in/etc/default/grub, - ruft
update-grubodergrub-mkconfig -o /boot/grub/grub.cfgauf (sofern vorhanden).
- ersetzt ggf.
-
Setzt das Btrfs-Default-Subvolume auf
@, sodass das System von@bootet. -
Stellt sicher, dass die benötigten Mountpoints auch im aktuellen Root existieren (
/home,/var/lib/docker, …). -
Validiert die neue
/etc/fstabautomatisch mitfindmnt --verify(rein lesend, mountet nichts live um) und bricht bei Problemen ab, bevor du versehentlich mit einer kaputten fstab neu startest.
Das Ergebnis:
- Root läuft von
@(Timeshift-kompatibel). - Wichtige Pfade wie
/home,/var/log,/var/lib/docker,/var/wwwliegen auf eigenen Subvolumes.
- Debian oder Debian-basiertes System mit:
aptsystemd
- Root-Dateisystem ist Btrfs auf einem einzelnen Device (z. B. eine Btrfs-Partition
/dev/vda2). - Das Skript wird als root ausgeführt.
Bei Bedarf installiert das Skript automatisch:
rsyncbtrfs-progs
Am unkompliziertesten auf einer frischen Server-Installation, da dort alle Verzeichnisse klein/leer sind. Das Skript funktioniert aber auch auf bereits laufenden Systemen, sofern genug freier Speicherplatz vorhanden ist (wird automatisch geprüft – jedes Byte auf
/wird während der Migration kurzzeitig dupliziert). Für eine konsistente Kopie werden bekannte Dienste (mongod,mysql,postgresql,docker) vor ihrer jeweiligen Datenkopie automatisch gestoppt und danach wieder gestartet.Trotzdem gilt auf laufenden Systemen: mach vorher ein Backup, plane ein Wartungsfenster für den abschließenden Neustart ein, und bedenke, dass Anwendungen außerhalb dieser Liste (z. B. Podman, ein eigener Webserver-Prozess mit offenen Dateien in
/srvoder/var/www) während der Kopie weiterlaufen und dadurch theoretisch eine inkonsistente Momentaufnahme in ihr Subvolume bekommen könnten.
-
Debian so installieren, dass du erhältst:
- eine kleine EFI-Partition (z. B.
/dev/vda1) - eine große Btrfs-Partition als Root (z. B.
/dev/vda2)
- eine kleine EFI-Partition (z. B.
-
Als root anmelden (oder
sudoverwenden). -
Repository klonen:
git clone https://github.com/<dein-user>/btrfs-layout-script.git cd btrfs-layout-script
-
Skript ausführbar machen:
chmod +x setup-btrfs.sh
-
Skript ausführen:
sudo ./setup-btrfs.sh
-
/etc/fstabprüfen und sicherstellen, dass:/mitsubvol=@eingetragen ist,- die zusätzlichen Pfade (
/home,/var/log,/var/lib/docker,/var/www, …) passende Einträge mit den erwarteten@…-Subvolumes haben.
-
Mounts anwenden und testen:
systemctl daemon-reload mount -a
Es sollten keine Fehler erscheinen.
-
Neustart:
reboot
-
Nach dem Neustart prüfen:
findmnt -o TARGET,SOURCE,FSTYPE,OPTIONS / findmnt -o TARGET,SOURCE,FSTYPE,OPTIONS /home /var/log /var/lib/docker /var/www
Erwartung:
/von...[/@]mitsubvol=@/homevon...[/@home]usw.
Damit ist das Layout für Timeshift und Container-Workloads vorbereitet.
Dieses Projekt steht unter der GNU General Public License Version 3 oder neuer (GPL-3.0-or-later).
Details findest du in der Datei LICENSE.