Ausgangslage
Wer meine letzten Beiträge verfolgt hat, dem ist es sicher nicht verborgen geblieben, dass ich für meinen neuen Rechner ein System gesucht hatte, welches die Lebensdauer der Hardware ohne große Eingriffe oder gar Neuinstallation übersteht. Und damit ich mich nicht verzettele, ist es mir stets wichtig, auf jedem meiner Rechner die gleiche Distribution zu haben (das ist unendlich cool und einfach mit NixOS! – kommt in Teil 3).
So landete ich dann irgendwann sehr zuversichtlich bei Gentoo. Wenn überhaupt, dann schafft das mutmaßlich nur der Paketmanager Portage über so einen langen Zeitraum; Belege dafür fand ich ausreichend. Allerdings muss man zur Einlösung dieses Stabilitäts-Versprechens die Systempflege absolut akkurat betreiben, auf jedem Rechner einzeln – das hat mich vollkommen überfordert, zeitlich und auch von der Kompetenz her.
Das Distro-Hopping ist nun aber endgültig beendet. NixOS übererfüllt meine Anforderungen – es ist brillant. Und entgegen häufiger Zuschreibungen kann ich berichten: NixOS ist (relativ) easy, weil die Logik so leicht nachvollziehbar ist. Neues Programm installieren: Einfach den entsprechenden Paketnamen in die Konfigurationsdatei schreiben. Update: Einen Befehl eingeben, that's it. Systempflege ist ein No-brainer.
Nur das initiale Set-up benötigt einmalig etwas Lernkurverei. Wenigstens in Grundzügen sollte man daher verstehen, wie NixOS tickt. Deshalb zunächst ein erster beschreibender Theorieteil, aber sehr bildhaft.
Fragmentierung ist unausweichlich
Wir alle sind mit dem imperativen Bauen unserer Systeme aufgewachsen und haben das nie hinterfragt. Für uns ist es selbstverständlich, dass wir uns das System nach unseren Vorstellungen, Vorlieben und Notwendigkeiten (Treiber etc.) Schritt für Schritt selbst zusammenbasteln, und das wichtigste Werkzeug dafür ist der Paketmanager. Manchmal ärgern wir uns, wenn das System eines Tages nicht die gewohnte oder erwartete Funktionalität und/oder Performance liefert. Im Extremfall setzen wir die Kiste dann neu auf; das ist eben so, damit hat man sich abgefunden. Viele von uns kennen es ganz krass von Windows. Nach geraumer Zeit der Nutzung wird das System unerträglich langsam und Fehlermeldungen häufen sich, die Neuinstallation wird unumgänglich. Aber auch Linux ist von diesem Verhalten nicht frei – keineswegs. Woran liegt das eigentlich?
(1) Der "Snowflake"-Effekt Jedes Mal, wenn wir eine Veränderung des Systems vornehmen, also ein Paket installieren, die Konfiguration verändern, einen Patch laufen lassen etc., wird das System immer individueller und einzigartiger. Wie eine Schneeflocke: Unmöglich, eine solche exakt zu kopieren oder wiederherzustellen, sollte diese schmelzen. In der Informatik ist das der "Mutable State", der veränderte und veränderbare Zustand. Der tägliche Wahnsinn für Servicetechniker:innen, egal ob vor Ort oder über Hotline. Unwahrscheinlich, dass User im Dialog alle je gemachten Eingaben und Änderungen beschreiben können, um dem Fehler auf die Spur zu kommen. Oft bleibt dann eben nur, den einen ultimativen definierten (Ur-)Zustand durch Neuinstallation herzustellen.
So viel sei schon mal verraten: Es ist kein Zufall, dass DIE herausragende Weiterentwicklung von NixOS "Flakes" heißt. Und das Logo ... schaut es mal an. Wir kommen im Teil 2 drauf.
(2) Die "Dependency Hell" Die "Hölle" bricht immer los, wenn man ein Systemupdate macht. Die neue Programmversion sagt, ich benötige die Laufzeitumgebung 2.0 und den Treiber XY. Es wird also auf 2.0 und XY aktualisiert. Ein anderes Programm ist aber nur für 1.5 optimiert und schon wird es kritisch. Vielleicht doch wieder versuchen, den Ursprungszustand herzustellen? Es ist ein Teufelskreis. Je nachdem, wie gut der Paketmanager mit solchen Herausforderungen umgehen kann, kommen die Probleme früher oder später, aber sie kommen; spätestens dann, wenn die Summe der Konflikte ein kritisches Maß überschritten hat.
Systeme fragmentieren also, weil sie versuchen, die globale Ordnung in einer Welt voller widersprüchlicher Anforderungen mit vielen einzelnen imperativen Gegenmaßnahmen zu halten. So kennen wir das bei allen gängigen Betriebssystemen (und der Weltordnung, welche auch zunehmend fragiler wird).
Der Paradigmenwechsel von Nix bzw. NixOS
Wenn die Erfahrung zeigt, dass die imperative Verwaltung unausweichlich problembehaftet ist, lohnt es sich vielleicht nicht, zwanghaft am System festzuhalten, sondern das Grundsätzliche mal neu zu denken. Ein solcher Paradigmenwechsel wurde mit Nix bzw. NixOS umgesetzt. Und zwar fabelhaft – keep it simple, but not simpler than it needs to be.
[!Note] Nix ist ein Paketmanager, welcher distributions- und sogar betriebssystemübergreifend verwendet werden kann. Maximal wirksam und konsequent ist es, wenn auch die Betriebssystem-Komponenten gemäß des neuen Ansatzes verwaltet werden, daher lieber gleich NixOS.
Ich möchte versuchen, das neue Paradigma am Beispiel einer Großküche in einem Restaurant bildhaft zu erklären.
Nach einigen Monaten oder Jahren des Betriebs quellen Schränke und Lagerräume mit angeschafften Kochutensilien, Gewürzen etc. völlig über. Man hat kaum Platz zum Arbeiten und sucht ewig nach den richtigen Zutaten. Reibscheiben verschiedener Gemüsehobel liegen nebeneinander, kompatibel sind diese nicht, dauernd vergreift man sich und es klemmt; Gewürze verstecken sich hinter anderen Zutaten im Schrank, das pure Chaos. Der Betrieb läuft einfach nicht rund, es werden Fehler gemacht und alles dauert länger.
Da die Situation nicht mehr tragbar ist, wechselt man zu einem neuen Küchenchef, dem Starkoch NixOS. Was man üblicherweise alles in einer Restaurantküche parat haben sollte und wie der Zustand der Küche zu dem geworden ist, wie er sich momentan darstellt, interessiert ihn nicht die Bohne! NixOS vollzieht einen vollständigen Paradigmenwechsel und stellt auf eine rein deklarative und funktionale Systematik um. Es gibt nur eine einzige Quelle der Wahrheit und das ist die Speisekarte!
Ein NixOS-System wird deterministisch aus hauptsächlich einer zentralen Konfigurationsdatei (der
configuration.nix) abgeleitet. Mit dieser Textdatei beschreibt der User deklarativ den gewünschten funktionalen Endzustand seines Systems. Und dies ist die einzige Quelle der Wahrheit. Wichtig für das Verständnis: Man baut das System nicht mehr selbst (das lässt man NixOS machen), sondern man beschreibt es nur - in einem vorgeschriebenen Syntax.
Die Speisekarte definiert somit den gesamten Zustand. Damit wird die Küche ausschließlich mit den Kochutensilien und mit den Zutaten bestückt, die zur Herstellung der beschriebenen Speisen in reproduzierbarer Qualität notwendig sind.
Über eine clevere Zuordnungsfunktion, abgebildet durch eine für jedes Gericht individuelle "Teilenummer", wird sichtbar, dass z. B. Curry von 'Speise 1' und 'Speise 2' gebraucht wird. Das Rezept wird also numerisch verschlüsselt. Wir kennen so was von Personalnummern, die sich vielleicht durch unseren Geburtstag und den Anfangsbuchstaben des Familiennamens mit aufbauen; die Nummer ist also ein Informationsträger.
Bei NixOS ist das ein kryptografischer 160-Bit-Hash, der aus allen Parametern berechnet wird, also alle Abhängigkeiten (sogar die verwendete
glibc-Version oder den Compiler) einbezieht.
Wenn die Speisekarte wechselt, was dann? Die Küche wird nach den Anforderungen der neuen Karte (also der veränderten configuration.nix) konsequent umgeräumt, die Speisekarte ist die einzige Quelle der Wahrheit. Den Plan dazu liefert eben diese individuelle und eindeutige "Teilenummer" für jedes Gericht, in welcher alle Informationen (Curry …, Gemüsehobel …) als numerisch-mathematisches Rezept verschlüsselt sind.
Starkoch NixOS lässt nach dem Editieren der neuen Speisekarte eine Update-Routine über alle Nummern laufen. Wird im Ergebnis (reine, eindeutige Mathematik) dann zu manchen Zutaten und Utensilien keine Zuordnung ausgespuckt, fliegt z. B. Curry aus der Küche raus. Benötigt man hingegen noch ein spezielles Küchengerät für eine Speise, wird es angeschafft und an den Zubereitungsplatz der zugehörigen Speise gestellt.
Nix übersetzt die neue Beschreibung in seiner neuen Gesamtheit in eine präzise, maschinenlesbare Bauanleitung, die alle notwendigen Eingaben, Abhängigkeiten und Build-Schritte spezifiziert.
Nixos verlangt außerdem, dass alle Zutaten und Utensilien zur Zubereitung von 'Speise 1' gesammelt an einem definierten und abgegrenzten Zubereitungsplatz für eben diese bereitliegen. Und dieses Ordnungssystem wird grundsätzlich für alle Speisen so angewendet.
Ein zentraler Baustein zur Vermeidung von Systemfragmentierung ist der Nix-Store in unserem Verzeichnisbaum, er ist das Lager für Pakete und Konfigurationsdateien. Der User muss hier nicht (und darf auch nicht) eingreifen, das erledigt NixOS für uns. Jedes Paket und jede Systemdatei wird dort in einem eigenen, isolierten Verzeichnis gespeichert.
Und tatsächlich funktioniert die Systemgastronomie auch nach solchen Grundsätzen. Schaut euch nur die Küchen – nein, falsch – schaut euch die Gerichte von McDoof an unterschiedlichen Orten an: identisch.
Angenommen, Starkoch NixOS möchte eine weltweite Kette "McNixOS" aufbauen, dann muss er allerdings berücksichtigen, dass sich die Gebäude baulich unterscheiden und noch viele andere abweichende äußerliche Rahmenbedingungen vorhanden sind. Diese Rahmenbedingungen für eine neue Filiale müssen im Lastenheft für den Bau dokumentiert und berücksichtigt werden.
Bei der Installation erfasst NixOS sehr präzise die Hardware und schreibt alle Informationen in die Datei
hardware-configuration.nix. Auch diese Informationen werden mit in den Hash aufgenommen und führen beim Bau des Systems z.B. zur Installation von Treibern.
Wenn die Rahmenbedingungen bekannt sind und somit durch Maßnahmen berücksichtigt werden können, ist es möglich, die Speisekarte an jedem beliebigen Ort identisch gleich umzusetzen.
Die Quelle der Wahrheit, also die
configuration.nixbestimmt auch auf einer anderen Hardware wie mit den veränderten Parametern gerechnet werden muss. Mathematisch exakt entsteht wieder das gleiche Ergebnis: ein Bit-genau identisches System wird gebaut, vollständig reproduzierbar.
Kurz zusammengefasst: Der User beschreibt, was er vorfinden möchte (configuration.nix), das Installationsprogramm klärt die Rahmenbedingungen (hardware-configuration.nix), NixOS selbst übersetzt das in eine maschinenlesbare Bauanleitung und administriert auch das System und den Nix-Store rein mathematisch und eindeutig reproduzierbar über die Hashes. All das wird durch einen einzigen Befehl des Users ausgelöst: sudo nixos-rebuild switch.
Das ist der Grundaufbau. Sofern mehrere User die gleiche Hardware nutzen (oder auch bei der üblichen Trennung zwischen Root und User) wird es für den einzelnen User noch einmal einfacher. Er beschreibt seine individuelle Wohnung in dem Nix-Haus dann nur über eine einzige Datei, der home.nix. Seht das ausschließliche Arbeiten mit der configuration.nix also nicht als Endpunkt, sondern nur als Fingerübung oder Zwischenlösung. Dazu aber erst in der nächsten Folge.
Eine Schnellstart-Anleitung
Installation
- Graphical ISO image von https://nixos.org/download herunterladen (dazu bis zu NixOS runter scrollen)
- ISO auf USB-Stick schreiben und von diesem booten
- Internetverbindung herstellen
- Dem grafischen Installer wie gewohnt folgen. Empfehlung: "allow unfree software" zulassen
- Reboot
- Internetverbindung herstellen
Wer es später einfacher bei der Übernahme meiner Konfiguration haben möchte, soll zunächst "nixos" als Hostname belassen.
Erste Konfigurationsschritte und Kennenlernen des Systems
[!Vorab] Man kann nichts kaputt machen. Selbst wenn man seine
configuration.nixvollständig zerstört, wählt man beim Boot einfach einen vorherigen Boot-Point und man hat den alten Zustand.
Terminal öffnen und die configuration.nix im Editor (hier Nano) öffnen:
sudo nano /etc/nixos/configuration.nix
Der Aufbau der Datei sieht wie im folgenden Ausschnitt aus. Unten zwischen den zwei geschweiften Klammern ist jeweils Platz für Befehle. Hier definiere ich einmalig den Programmbereich und trage da einfach meine gewünschten Pakete ein. (Einrückungen am besten immer mit je zwei Leerzeichen, keine Tabulatoren.) NixOS hat das allergrößte(!) Repositorium, von da den richtigen Paketnamen auslesen.
{ config, pkgs, ... }:
{
# Programme (normale Binärpakete)
environment.systemPackages = with pkgs; [
thunderbird # Mailprogramm
libreoffice-fresh # Office-Suite (neueste Version)
hunspell # Rechtschreibprüfung-Engine
hunspellDicts.de_DE # Deutsches Wörterbuch
mythes # Thesaurus für LibreOffice
languagetool # Grammatik- und Stilprüfung
];
# Firefox als NixOS-Modul (kein Eintrag in systemPackages nötig)
programs.firefox = {
enable = true;
languagePacks = [ "de" ];
};
}
Ich kann es verstehen, wenn man an dieser Stelle abbrechen möchte, weil es kompliziert aussieht. Aber bitte kurz innehalten – es ist objektiv nicht schwieriger als das Aufrufen und Bedienen eines Paketmanagers über die Kommandozeile. Für mich ist dieses Vorgehen überdies viel transparenter und einfacher zu nachvollziehen als die Black Box eines Paketmanagers.
Speichern: STRG+O und ENTER, dann den Editor mit STRG+X verlassen.
sudo nixos-rebuild switch # System bauen - fertig!
[!Hinweis] Warum Firefox als NixOS-Modul? Es gibt nur ganz wenige Programme, die als Modul installiert werden. Module existieren ausschließlich nur für Programme die eine tiefe Systemintegration brauchen. Und ein Browser gehört als systemimmanentes Programm dazu. Alle anderen Programme "installiert" man ganz normal als Pakete.
Deinstallieren gibt es übrigens im herkömmlichen Sinne nicht. Würde ich oben thunderbird löschen oder mit # auskommentieren, beschreibe ich ja deklarativ einen anderen gewünschten Systemzustand. Und der wird mir durch sudo nixos-rebuild switch auch wie gewünscht gebaut, also dann ohne Thunderbird.
Hat man länger nichts an der Konfiguration geändert, sollte man wenigstens gelegentlich ein Update fahren.
sudo nixos-rebuild switch --upgrade # Turnusmäßiges Update!
Vorschläge zur Weiterarbeit
(1) Schau dir mal in Ruhe den Syntax der configuration.nix an und versuche, die Angaben und die Systematik zu verstehen. Mehr dazu auch in Teil 2. Du wirst unter anderem die Zeile i18n.defaultLocale = "de_DE.UTF-8"; sehen. Durch diese wird in allen Programmen (sofern verfügbar) die deutsche Benutzeroberfläche praktischerweise automatisch mitinstalliert (evtl. muss sie im Programm noch ausgewählt werden).
(2) Sofern bislang nicht vorhanden, hol dir einen Account bei codeberg.org und lege dort ein Repo mit dem Namen "NixOS" an. Das nutzen wir dann im Teil 2.
(3) Solltest du schon wild experimentieren oder Fragen haben: einfach Terminal-Ausgaben oder Fragen z. B. in claude.ai (Empfehlung für Linux-Themen) reinnageln … Ich bin nur ein mieser kleiner User und mache es auch so.
Quellen:
Inspiration gab mir ein Blog-Beitrag: [https://joshblais.com/blog/nixos-is-the-endgame-of-distrohopping/]()
Offizielle Dokumentation: https://nixos.org/learn/
Titelbild und Wallpaper: [https://hdqwalls.com/linux-nixos-wallpaper](https://hdqwalls.com/linux-nixos-wallpaper)
