NixOS: Der umfassende Leitfaden vom Paketmanager Nix für Anfänger

Nix ist ein einzigartiger, rein funktionaler Paketmanager, der sich durch reproduzierbare, deklarative und zuverlässige Paketverwaltung auszeichnet. Anders als traditionelle Paketmanager verwendet Nix ein einzigartiges Konzept der unveränderlichen Pakete und isolierten Umgebungen.

Grundlegende Konzepte

Der Nix Store

Alle Pakete werden im Nix Store unter /nix/store gespeichert.

Jedes Paket erhält einen eindeutigen Hash-basierten Pfad:

Bash
/nix/store/2727m90vgx8bbirkaqvry3h4n3mlqr4n-firefox-119.0/

Was bedeutet der Pfad?

  • 2727m90v...: Hash aller Build-Inputs
  • firefox: Paketname
  • 119.0: Version
Nix-Profile

Profile sind Benutzerumgebungen, die Pakete zusammenfassen.

Aktuelles Profil anzeigen

Bash
nix profile list

Beispielausgabe

Bash
0 firefox-119.0   2024-01-20 /nix/store/2727m90v...
1 vim-9.0.1503    2024-01-20 /nix/store/6qz9m1v...
Die configuration.nix (NixOS)
Bash
{ config, pkgs, ... }:
{
  environment.systemPackages = with pkgs; [
    firefox
    vim
    git
  ];
}

Pakete installieren

Grundlegende Installation

Mit nix-env (traditionell)

Bash
nix-env -iA nixpkgs.firefox

Beispielausgabe:

Bash
resolving 'firefox' from nixpkgs...
building '/nix/store/2727m90vgx8bbirkaqvry3h4n3mlqr4n-user-environment.drv'...
installing 'firefox-119.0'
building path(s) '/nix/store/2727m90vgx8bbirkaqvry3h4n3mlqr4n-firefox-119.0'

Mit nix profile (modern)

Bash
nix profile install nixpkgs#firefox

⚠️ WICHTIGE HINWEISE:

  • Nix erstellt für jede Installation einen eigenen Store-Pfad
  • Mehrere Versionen können parallel existieren
  • Rollbacks sind jederzeit möglich
Erweiterte Optionen

Spezifische Version installieren

Bash
nix-env -iA nixpkgs.firefox-102-esr

Aus einem bestimmten Channel

Bash
nix-env -iA nixos-23.11.firefox

Flakes verwenden (modern)

Bash
nix profile install github:NixOS/nixpkgs#firefox

Paketmanagement

Profile verwalten

Profile auflisten

Bash
nix profile list

Beispielausgabe:

Bash
Index:    0
Name:     firefox
Version:  119.0
Path:     /nix/store/2727m90v..-firefox-119.0
Generationen verwalten

Generationen anzeigen:

Bash
nix-env --list-generations

Zu einer Generation wechseln

Bash
nix-env --switch-generation 42

Alte Generationen löschen

Bash
nix-env --delete-generations old
Pakete aktualisieren

Einzelnes Paket aktualisieren

Bash
nix-env -u firefox

Alle Pakete aktualisieren

Bash
nix-env -u

⚠️ WARNUNG:

  • Prüfe immer die Änderungen vor dem Update
  • Beachte mögliche Breaking Changes
Pakete entfernen

Mit nix-env

Bash
nix-env -e firefox

Mit nix profile

Bash
nix profile remove nixpkgs#firefox

Deklarative Paketverwaltung

In configuration.nix

TypeScript
{ config, pkgs, ... }:
{
  environment.systemPackages = with pkgs; [
    firefox
    (vim_configurable.override {
      python3Support = true;
    })
    git
  ];
}

Änderungen anwenden:

Bash
sudo nixos-rebuild switch
Flakes verwenden
TypeScript
{
  description = "My System Configuration";
  
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.11";
  };
  
  outputs = { self, nixpkgs }: {
    nixosConfigurations.mysystem = nixpkgs.lib.nixosSystem {
      system = "x86_64-linux";
      modules = [ ./configuration.nix ];
    };
  };
}

Die Nix-Sprache

Grundlegende Syntax

Einfache Ausdrücke

Bash
# Attribute Set
{
  name = "firefox";
  version = "119.0";
  buildInputs = [ gtk3 dbus ];
}

# Listen
[ firefox vim git ]

# Funktionen
pkg: pkg.override { enableGUI = true; }
Derivations erstellen

Einfache Derivation

Bash
derivation {
  name = "hello-2.12";
  builder = "${bash}/bin/bash";
  args = [ ./builder.sh ];
  system = "x86_64-linux";
  src = fetchurl {
    url = "mirror://gnu/hello/hello-2.12.tar.gz";
    sha256 = "0ssi1wpaf7plaswqqjwigppsg5fyh99vdlb9kzl7c9lng89ndq1i";
  };
}

⚠️ WICHTIG:

  • Derivations sind die Bauanleitungen für Pakete
  • Alle Abhängigkeiten müssen explizit angegeben werden
  • Builds sind reproduzierbar

Fortgeschrittene Paketierung

Overlays verwenden

Overlay definieren

~/.config/nixpkgs/overlays/custom.nix

TypeScript
self: super: {
  firefox = super.firefox.override {
    enableTridactylNative = true;
  };
}

System-weites Overlay

configuration.nix

TypeScript
{
  nixpkgs.overlays = [
    (import ./overlays/custom.nix)
  ];
}
Eigene Pakete erstellen

Default.nix

TypeScript
{ stdenv, lib, fetchFromGitHub }:

stdenv.mkDerivation rec {
  pname = "mein-programm";
  version = "1.0.0";

  src = fetchFromGitHub {
    owner = "username";
    repo = "mein-programm";
    rev = "v${version}";
    sha256 = "...";
  };

  buildInputs = [ ];

  meta = with lib; {
    description = "Mein eigenes Programm";
    homepage = "https://github.com/username/mein-programm";
    license = licenses.mit;
    platforms = platforms.linux;
  };
}

Entwicklungsumgebungen

nix-shell

Shell.nix erstellen

TypeScript
{ pkgs ? import <nixpkgs> {} }:

pkgs.mkShell {
  buildInputs = with pkgs; [
    python3
    poetry
    nodejs
    yarn
  ];

  shellHook = ''
    export PYTHONPATH="${pkgs.python3}/bin/python"
  '';
}
Entwicklungsumgebung starten
Bash
nix-shell

Oder mit Flakes

Bash
nix develop
direnv Integration

.envrc erstellen

Bash
use nix

direnv aktivieren

Bash
direnv allow

Garbage Collection

Nix Store bereinigen

Manuelle Bereinigung

Nicht mehr benötigte Pakete entfernen:

Bash
nix-collect-garbage

Alte Generationen löschen:

Bash
nix-collect-garbage -d

Automatische Bereinigung

configuration.nix

TypeScript
{
  nix.gc = {
    automatic = true;
    dates = "weekly";
    options = "--delete-older-than 30d";
  };
}

⚠️ WARNUNG:

  • Sichere wichtige Generationen vor der Bereinigung
  • Prüfe aktive Prozesse
  • Beachte Rollback-Möglichkeiten

Best Practices

System-Konfiguration

Modulare Konfiguration

/etc/nixos/configuration.nix

TypeScript
{
  imports = [
    ./hardware-configuration.nix
    ./desktop.nix
    ./development.nix
    ./services.nix
  ];
}

Flakes-Struktur

Markdown
.
├── flake.nix
├── flake.lock
└── modules/
    ├── desktop/
    │   ├── default.nix
    │   ├── kde.nix
    │   └── gnome.nix
    ├── development/
    └── services/
Reproduzierbarkeit sicherstellen

Versionen fixieren

TypeScript
{
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.11";
    home-manager = {
      url = "github:nix-community/home-manager/release-23.11";
      inputs.nixpkgs.follows = "nixpkgs";
    };
  };
}

Troubleshooting

Häufige Probleme und Lösungen

Konfliktlösung

Build-Fehler analysieren:

Bash
nix-build --show-trace

Abhängigkeiten prüfen:

Bash
nix-store -q --references /nix/store/<hash>-package

Store-Reparatur

Store-Konsistenz prüfen:

Bash
nix-store --verify

Beschädigte Pfade reparieren:

Bash
nix-store --repair-path /nix/store/<hash>-package
Debug-Techniken

Debug-Shell

TypeScript
stdenv.mkDerivation {
  # ...
  shellHook = ''
    export NIX_DEBUG=1
    export NIX_LOG_PATH=/tmp/nix-build.log
  '';
}

Build-Logs analysieren

Bash
nix log /nix/store/<hash>

Detaillierte Build-Ausgabe:

Bash
nix-build -K . |& tee build.log

Fortgeschrittene Anwendungsfälle

Container und VMs

NixOS-Container

configuration.nix

TypeScript
{
  containers.myapp = {
    config = { config, pkgs, ... }: {
      system.stateVersion = "23.11";
      services.nginx.enable = true;
    };
  };
}

VM-Images erstellen

Bash
nix-build '<nixpkgs/nixos>' -A config.system.build.virtualBoxImage
CI/CD-Integration

GitHub Actions

TypeScript
name: "Build"
on:
  pull_request:
  push:
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3
    - uses: cachix/install-nix-action@v22
    - run: nix build .#
Performance-Optimierung

Binary Cache einrichten

TypeScript
{
  nix = {
    settings = {
      substituters = [
        "https://cache.nixos.org"
        "https://mycache.org"
      ];
      trusted-public-keys = [
        "cache.nixos.org-1:..."
        "mycache.org-1:..."
      ];
    };
  };
}

Build-Parallelisierung

TypeScript
{
  nix.settings = {
    max-jobs = "auto";
    cores = 0;
    sandbox = true;
  };
}

Sicherheit und Wartung

Regelmäßige Wartungsaufgaben

Update-Routine

System aktualisieren:

Bash
sudo nixos-rebuild switch --upgrade

Store bereinigen:

Bash
sudo nix-collect-garbage -d

Bootloader-Einträge aufräumen:

Bash
sudo /run/current-system/bin/switch-to-configuration boot

Sicherheits-Checks

Verwaiste Pakete finden:

Bash
nix-store --gc --print-dead

Nicht referenzierte Pfade finden:

Bash
nix-store --verify --check-contents

Expertentipps

Systemoptimierung

Speicherplatz sparen

TypeScript
{
  nix.settings.auto-optimise-store = true;
  nix.optimise.automatic = true;
}

Build-Cache optimieren

TypeScript
{
  nix.settings = {
    keep-outputs = true;
    keep-derivations = true;
  };
}
Debugging und Entwicklung

Nix-Repl nutzen

Bash
nix repl
nix-repl> :l <nixpkgs>
nix-repl> firefox.buildInputs

Store analysieren

Abhängigkeitsgraph erstellen:

Bash
nix-store -q --graph /nix/store/<hash> | dot -Tpng > graph.png

Abschließende Empfehlungen

  1. Dokumentation pflegen
    • Konfigurationsänderungen dokumentieren
    • Build-Skripte kommentieren
    • Abhängigkeiten dokumentieren
  2. Backup-Strategie
    • Regelmäßige Konfigurationsbackups
    • Wichtige Generationen sichern
    • Binary Caches spiegeln
  3. Community-Ressourcen nutzen
    • NixOS Discourse Forum
    • GitHub Discussions
    • IRC/Matrix Channels

Wichtige Ressourcen

Offizielle Dokumentation
Community-Ressourcen
Entwickler-Ressourcen
Lernressourcen

Fazit

Nix und NixOS bieten einen einzigartigen, deklarativen Ansatz zur Paketverwaltung und Systemkonfiguration. Die Kombination aus unveränderlichen Paketen, reproduzierbaren Builds und atomaren Updates macht Nix zu einem besonders leistungsfähigen Werkzeug für Systemadministratoren und Entwickler. Die anfängliche Lernkurve mag steil sein, aber die Vorteile der reproduzierbaren und zuverlässigen Systemverwaltung überwiegen bei weitem.

⚠️ Wichtiger Hinweis:

Nix und NixOS entwickeln sich ständig weiter, insbesondere mit der Einführung von Flakes und neuen Experimentalfeatures. Überprüfe regelmäßig die offizielle Dokumentation auf Änderungen und neue Funktionen. Die hier beschriebenen Methoden können sich mit der Zeit ändern. Mit diesem umfassenden Wissen und den zur Verfügung stehenden Ressourcen bist du gut gerüstet, um dein System effektiv mit Nix zu verwalten.

Denk immer daran: Mit der wachsenden Adoption von Nix und der aktiven Community wird das Ökosystem ständig verbessert und erweitert.

Aktualisierungen und Änderungen

Dieser Artikel wird regelmäßig aktualisiert, um neue Entwicklungen und Best Practices zu berücksichtigen. Die letzte Aktualisierung erfolgte am 24. Oktober 2024.

Kommentar verfassen