Da Debian von Haus aus ext4 als Dateisystem benutzt, muss man bei einer Installation noch einiges manuell erledigen um btrfs zu nutzen.
Die grundlegende Konfiguration habe ich aus zwei Tutorials zusammengebaut (beide auf englisch)
- Installing Debian with BTRFS, Snapper backups and GRUB-BTRFS
- Creating openSUSE-style btrfs root partition & subvolumes
Da dies primär eine Orientierung für mich selbst ist, empfiehlt es sich die beiden Artikel durchzulesen um gegebenenfalls eigene Anpassungen vorzunehmen!
Da chattr
aus irgend einem Grund in der Konsole der Installation bei Debian nicht verfügbar ist, muss man erstens eine Live-Version von Debian benutzen und zweitens den Installtaionsprozess zweimal starten!
Es empfiehlt sich ein Live-Version ohne Desktopumgebung zu benutzen da diese schneller lädt!
Installation / Partitionierung
Für die Installation wähle ich Advanced Install Options
, Text installer...
und dann Expert install
.
Danach konfiguriere ich mal alles entsprechend meinen Bedürftnissen bis ich zur Partitionierung komme.
Falls man einen Desktop PC aufsetzt der auch Winterschlaf halten können soll, muss man bereits beim Starten des Installationsprozesses ein bisschen wie folgt herumfummeln:
Beim Eintrag, mit dem man die Installation starten will, drück man e
und fügt dann folgendes hinter linux /install.amd/vmlinuz
mit einem Abstand ein:
partman-auto/cap-ram=n
oder
partman-auto/cap-ram=(value in MB z.b. 1024 für 1GB)
Anschliessend startet man mit ctrl + x
oder F10
die Installation
(gefunden hier)
- Choose Language: Deutsch - Schweiz - Schweiz
- Tastatur konfigurieren: Schweizerdeutsch
- Installationsmedium erkennen und einbinden
- Installer-Komponenten vom Installationsmedium laden
- Netzwerkhardware erkennen
- Netzwerk einrichten: da ich das System als Server nutze konfiguriere ich hier eine statische IP
- Benutzer und Passwörter einrichten:
- root anmelden: ja
- Benutzerkonto erstellen: nein
- Uhr einstellen
- Festplatte erkennen
- Festplatte partitionieren
Da wähle ich die automatische Konfiguration der gesamten Platte.
Ich benötige nur 1GB für swap da ich später zram für das swapping verwenden werde.
Die grösste Partition für das root-Verzeichnis /
ändere ich dann noch von ext4 auf btrfs!
Dann schliesse ich die Partitionierung ab.
BtrFS
Bevor man nun das Basissystem installiert, muss man noch einiges über die Konsole konfigurieren damit dann auch Snapshots funktionieren.
Um in die Konsole zu gelangen drückt man ctrl + alt + f2
(Um wieder zur Installation zurückzukehren benutzt man ctrl + alt + f1
)
In der Konsole benutze ich erstmal df
um zu sehen was alles gemounted ist.
Dabei merke ich mir gleich noch die Partition die auf /target
gemounted ist; in meinem Fall ist das /dev/sda2
Für mich wichtig ist /target
und /target/boot/efi
.
Die muss ich jetzt erstmal alle unmounten und zwar in dieser Reihenfolge:
umount /target/boot/efi/
umount /target/
Nun mounte ich meine /dev/sda2
auf /mnt
mount /dev/sda2 /mnt
Wenn ich nun in das Verzeichnis /mnt
wechsle und ls
eingebe, dann sehe ich da ein @rootfs
.
Dies ist für Snapper ungünstig weshalb ich das auf @
ändere
mv @rootfs/ @
Subvolumes
Nun erstelle ich die Subvolumes nach Vorlage von OpenSUSE.
Weshalb OpenSUSE?
OpenSUSE nutzt BtrFS seit einigen Jahren als default Dateisystem und hat deshalb Erfahrung mit der Struktur und Konfiguration des Layouts.
btrfs subvolume create /mnt/@/.snapshots
mkdir /mnt/@/.snapshots/1
btrfs subvolume create /mnt/@/.snapshots/1/snapshot
mkdir -p /mnt/@/boot/grub2/
btrfs subvolume create /mnt/@/boot/grub2/i386-pc
btrfs subvolume create /mnt/@/boot/grub2/x86_64-efi
btrfs subvolume create /mnt/@/home
btrfs subvolume create /mnt/@/opt
btrfs subvoulme create /mnt/@/root
btrfs subvolume create /mnt/@/srv
btrfs subvolume create /mnt/@/tmp
mkdir /mnt/@/usr/
btrfs subvolume create /mnt/@/usr/local
btrfs subvolume create /mnt/@/var
Nun erstelle ich die benötigten Verzeichnisse
mkdir /mnt/.snapshots
mkdir -p /mnt/boot/grub2/i386-pc
mkdir -p /mnt/boot/grub2/x86_64-efi
mkdir /mnt/home
mkdir /mnt/opt
mkdir /mnt/root
mkdir /mnt/srv
mkdir /mnt/tmp
mkdir -p /mnt/usr/local
mkdir /mnt/var
Danach kann ich die Konsole mit exit
wieder verlassen.
Chattr
Wie oben bereits erwähnt ist in der Installationskonsole von Debian kein chattr
verfügbar.
Dies wird aber benötigt um Copy-on-Write (CoW) für /var
zu deaktivieren.
Da in diesem Verzeichnis die Logs, Datenbanken und sonstige Dateien liegen welche häufig geschrieben/geändert werden bzw. sehr gross sein können, wird durch CoW das Dateisystem stark fragmentiert, was selbst auf SSD/Nvme irgendwann zu Performanceeinbussen führen kann.
Da die Festplatte bereits vorbereitet ist, breche ich die Installation hier ab und boote in das Live-System.
Hier mounte ich die Festplatte und deaktiviere anschliessend CoW für /var
.
Anmerkung: auf einem amerikanischen Keyboard liegt @ auf shift + 2
, / auf -
und + auf ^
.
sudo mount /dev/sda2 /mnt
sudo chattr +C /mnt/@/var
Nun reboote ich die Maschine und starte anschliessend die Installation erneut
sudo reboot
Installation (2. Durchlauf)
Nun konfiguriere ich wieder alles wie oben bis und mit "Festplatte erkennen".
Obwohl die Festplatte eigentlich vorbereitet ist, muss ich die Partitionierung trotzdem noch einmal durchlaufen und auf der Partition sda2
den Einhängepunkt auf /
setzen.
Dies ist nötig damit der Installer eine fstab anlegt die ich anschliessend noch benötige.
Vorsicht: doppelt checken dass auf der sda2
KEINE daten gelöscht werden bzw. die Partition NICHT formatiert wird. Sonst wäre die ganze vorherige Arbeit wieder verloren!
Nun gehe ich mit ctrl + alt + f2
wieder in die Konsole und unmounte die beiden Einhängepunkte der sda2 wieder
umount /target/boot/efi/
umount /target/
Durch das erneute Partitionieren wird erneut ein subvolume @rootfs
erstellt welches ich noch löschen muss.
mount /dev/sda2 /mnt
btrfs subvolume delete /mnt/@rootfs
umount /mnt
Anschliessend wird alles wieder auf /target
gemountet um das Betriebssystem zu installieren.
Anmerkung: Ich benutze die Kompression zstd:3 weil ich das Betriebssystem auf eine mechanische HDD installiere und eine gute CPU habe.
mount -o noatime,space_cache=v2,compress-force=zstd:3,discard=async,subvol=@ /dev/sda2 /target
mount -o noatime,space_cache=v2,compress-force=zstd:3,discard=async,subvol=@/.snapshots /dev/sda2 /target/.snapshots
mount -o noatime,space_cache=v2,compress-force=zstd:3,discard=async,subvol=@/boot/grub2/i386-pc /dev/sda2 /target/boot/grub2/i386-pc
mount -o noatime,space_cache=v2,compress-force=zstd:3,discard=async,subvol=@/boot/grub2/x86_64-efi /dev/sda2 /target/boot/grub2/x86_64-efi
mount -o noatime,space_cache=v2,compress-force=zstd:3,discard=async,subvol=@/home /dev/sda2 /target/home
mount -o noatime,space_cache=v2,compress-force=zstd:3,discard=async,subvol=@/opt /dev/sda2 /target/opt
mount -o noatime,space_cache=v2,compress-force=zstd:3,discard=async,subvol=@/root /dev/sda2 /target/root
mount -o noatime,space_cache=v2,compress-force=zstd:3,discard=async,subvol=@/srv /dev/sda2 /target/srv
mount -o noatime,space_cache=v2,compress-force=zstd:3,discard=async,subvol=@/tmp /dev/sda2 /target/tmp
mount -o noatime,space_cache=v2,compress-force=zstd:3,discard=async,subvol=@/usr/local /dev/sda2 /target/usr/local
mount -o noatime,space_cache=v2,compress-force=zstd:3,discard=async,subvol=@/var /dev/sda2 /target/var
mount /dev/sda1 /target/boot/efi
fstab
Damit die BtrFS subvolumes nach der Installation auch richtig eingebunden werden muss ich noch die /target/etc/fstab
anpassen.
nano /target/etc/fstab
Ich orientiere mich an der ursprünglichen ersten Zeile (vorallem die UUID)
UUID={meine UUID der disk} / btrfs noatime,space_cache=v2,compress-force=zstd:3,discard=async,subvol=@ 0 0
UUID={meine UUID der disk} /.snapshots btrfs noatime,space_cache=v2,compress-force=zstd:3,discard=async,subvol=@/.snapshots 0 0
UUID={meine UUID der disk} /boot/grub2/i386-pc btrfs noatime,space_cache=v2,compress-force=zstd:3,discard=async,subvol=@/boot/grub2/i386-pc 0 0
UUID={meine UUID der disk} /boot/grub2/x86_64-efi btrfs noatime,space_cache=v2,compress-force=zstd:3,discard=async,subvol=@/boot/grub2/x86_64-efi 0 0
UUID={meine UUID der disk} /home btrfs noatime,space_cache=v2,compress-force=zstd:3,discard=async,subvol=@/home 0 0
UUID={meine UUID der disk} /opt btrfs noatime,space_cache=v2,compress-force=zstd:3,discard=async,subvol=@/opt 0 0
UUID={meine UUID der disk} /root btrfs noatime,space_cache=v2,compress-force=zstd:3,discard=async,subvol=@/root 0 0
UUID={meine UUID der disk} /srv btrfs noatime,space_cache=v2,compress-force=zstd:3,discard=async,subvol=@/srv 0 0
UUID={meine UUID der disk} /tmp btrfs noatime,space_cache=v2,compress-force=zstd:3,discard=async,subvol=@/tmp 0 0
UUID={meine UUID der disk} /usr/local btrfs noatime,space_cache=v2,compress-force=zstd:3,discard=async,subvol=@/usr/local 0 0
UUID={meine UUID der disk} /var btrfs noatime,space_cache=v2,compress-force=zstd:3,discard=async,subvol=@/var 0 0
Danach kann ich die Konsole mit exit
wieder verlassen.
Nun sollte dei Festplatte bereit für die Installation sein und ich kann mit ctrl + alt + f1
wieder zurück in die grafische Oberfläche und das Basissystem installieren.
- Art der Installation: normal
- zu installierender Kernel: linux-image-amd64
- Treiber: generisch
- Paketmanager konfiguriere:
- ein weiteres Installationsmedium einbinden: nein
- Mirror verwenden: ja, http
- Nicht-freie-Firmware: ja
- Nicht-freie-Software (Non-OSS): ja
- Paketdepots (Source): ja
- Sicherheitsaktualisierung, Release Updates und Backport aktivieren
- Software auswählen und installieren: keine automatischen Updates
da ich einen Server aufsetze wähle ich nur- SSH Server
- Standard Systemwerkzeuge
- GRUB Bootloader installieren
- Bootloader auf EFI erzwingen: nein
- NVRAM aktualisieren: ja
- OS Probe: nur bei Dual-Boot sinnvoll
- Installation abschliessen
- System auf UTC: nein
Nun ist das System installiert.
Jetzt müssen noch ein paar weitere Anpassungen vorgenommen werden.
Snapshots
Als erstes muss Snapper installiert und eine config erstellt werden.
Dazu muss ich auch das .snapshot Subvolume wieder löschen weil es von Snapper automatisch erstellt wird.
apt install snapper
btrfs subvolume delete /.snapshots
snapper -c root create-config /
Falls das Kommando btrfs
nicht gefunden wurde, muss man noch btrfs-progs
installieren
apt install btrfs-progs
GRUB-Btrfs
Da grub-btrfs nicht in den Debian Repositories ist, muss ich es manuell installieren.
grub-btrfs wird benötigt um direkt in snapshots booten zu können.
apt install git make inotify-tools
cd
git clone https://github.com/Antynea/grub-btrfs.git
cd grub-btrfs
make install
systemctl enable grub-btrfsd
systemctl start grub-btrfsd
Nun muss man noch ein paar Anpassungen machen, z.B. das Erstellen von Snapshots beim Booten deaktivieren
systemctl disable snapper-boot.timer
Man kann dann noch weitere Dinge anpassen auf die ich hier nicht näher eingehen werde.
Das oben verlinkte Tutorial bietet eine gute Grundlage und Erklärungen dazu.
Dann erstelle ich meinen ersten Snapshot mit
snapper -c root create --description "default fresh install"
zram
zram ist auf Debian einfach zu installieren; man muss es eigentlich nur installieren und aktivieren
apt install zram-tools
systemctl enable --now zramswap
Da zram standardmässig mit nur 256MB started, passe ich die Konfiguration an und gebe zram 50% des Arbeitsspeichers
nano /etc/default/zramswap
# Compression algorithm selection
# speed: lz4 > zstd > lzo
# compression: zstd > lzo > lz4
# This is not inclusive of all that is available in latest kernels
# See /sys/block/zram0/comp_algorithm (when zram module is loaded) to see
# what is currently set and available for your kernel[1]
# [1] https://github.com/torvalds/linux/blob/master/Documentation/blockdev/zram.txt#L86
#ALGO=lz4
# Specifies the amount of RAM that should be used for zram
# based on a percentage the total amount of available memory
# This takes precedence and overrides SIZE below
PERCENT=50
# Specifies a static amount of RAM that should be used for
# the ZRAM devices, this is in MiB
#SIZE=256
# Specifies the priority for the swap devices, see swapon(2)
# for more details. Higher number = higher priority
# This should probably be higher than hdd/ssd swaps.
#PRIORITY=100
Anschliessend zram neustarten damit die Änderungen übernommen werden
zramswap restart
Server
Da ich die Kiste als Server mit Virtualmin, Docker, Postgresql, diversen PHP-Versionen und elasticsearch nutzen will, muss ich noch ein paar zusätzliche Repositories hinzufügen und Pakete installieren.
Ich werde den Vorgang nur rudimentär beschreiben, also ohne zusätzlich auf Konfigurationen einzugehen.
Als erstes installiere ich Virtualmin da damit schon sehr viele Dinge automatisch installiert und konfiguriert werden.
apt install curl apt-transport-https lsb-release ca-certificates
sh -c "$(curl -fsSL https://software.virtualmin.com/gpl/scripts/virtualmin-install.sh)" -- --bundle LAMP
Dieser Vorgang kann einige Zeit dauern.
Bei meiner VM mit 4 vCores (AMD Ryzen 7 3700X) und 16GB vRam dauerte es ungefähr 15-20 Minuten.
Zuerst installiere ich mal Alles das ich zusätzlich benötige und nicht standardmässig installiert ist
apt install postgresql redis nginx python3-dev python-is-python3 amavisd-new libmagickcore-6.q16-6-extra ghostscript
Anmerkung: ich benutze zwar Apache2 als Standard-Webserver, allerdings hat sich gezeigt dass für das Proxying einiger föderierter Server die Konfiguration über Nginx einfacher ist (Apache -> Nginx -> Server).
Dann werden die zusätzlichen Repositories hinzugefügt
Repositories
Ich benötige diverse Versionen von PHP (Debian 12 Standard ist 8.2), Docker und Elasticsearch.
Je nach dem ob man Elasticsearch 7 (z.b. für Adobe Commerce) oder 8 installieren will muss man die URL und Source-List entsprechend von 8.x
auf 7.x
anpassen
curl -sSL -o /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg
sh -c 'echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/sury-debian-php-$(lsb_release -sc).list'
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc
chmod a+r /etc/apt/keyrings/docker.asc
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
tee /etc/apt/sources.list.d/docker.list > /dev/null
wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | gpg --dearmor -o /usr/share/keyrings/elasticsearch-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/elasticsearch-keyring.gpg] https://artifacts.elastic.co/packages/8.x/apt stable main" | tee /etc/apt/sources.list.d/elastic-8.x.list
apt update
apt install php{5.6,7.4,8.2,8.3}-{apcu,bcmath,cgi,cli,curl,fpm,gd,gmp,igbinary,imagick,imap,intl,mbstring,mysql,opcache,pdo,redis,soap,sqlite3,xml,zip} docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin elasticsearch smartmontools
a2enmod headers
a2enmod remoteip