NixOS
Table of Contents
NixOS auf dem GPD MicroPC 2: Reproduzierbar, aktuell und unterwegs zu Hause⌗
Ich habe nach einem Immutable Linux gesucht – und bin bei NixOS gelandet. Auf dem GPD MicroPC 2, einem 7-Zoll-Handheld mit Daumentastatur und Klappdisplay, soll es laufen. Die Anforderungen waren klar:
- Modernste Software: aktueller Kernel, aktuelle Desktop-Umgebung, aktuelle Apps
- Reproduzierbar: Das ganze System soll aus einer einzigen Textdatei entstehen
- Mobil einsetzbar: Touch, Auto-Rotation, vernünftige Energieverwaltung, verschlüsselte Platte
- Professionell: VMs, Container, Android-Apps, FIDO2, saubere Rollbacks
In diesem Artikel zeige ich den Installationsweg (NixOS mit
GNOME-Installer
installieren, danach per nixos-rebuild auf die eigene Konfiguration umschwenken) die komplette configuration.nix findest du am
Ende
meines Artikels.
Warum NixOS?⌗
„Immutable“ heißt bei den meisten Distributionen: ein schreibgeschütztes Basissystem als Image (Fedora Silverblue, bootc-Systeme und Ähnliche). NixOS geht einen anderen Weg und ist deshalb für dieses Projekt spannender:
- Das System ist Code. Alles – Bootloader, Verschlüsselung, Dienste, Desktop, Pakete – steht in einer Datei. Wer dieselbe Datei auf einer anderen Maschine baut, bekommt dasselbe System.
/nix/storeist schreibgeschützt. Installierte Software liegt unveränderlich unter eindeutigen Hashes. Nichts „driftet“ über die Jahre.- Generationen und Rollback. Jeder
nixos-rebuilderzeugt eine neue Systemgeneration. Geht etwas schief, wählt man im Bootmenü einfach die vorherige. - Aktuell bleiben ist einfach. Mit
linuxPackages_latestkommt der neueste Kernel, die Desktop-Umgebung kommt aus dem aktuellen Release, und für alles, was noch frischer sein soll, gibt es Flatpak, Distrobox undnix shell.
Ehrlich gesagt ist NixOS nicht „immutable“ im Sinne eines ostree-Images – es ist deklarativ und reproduzierbar. Für meinen Zweck ist das genau das, was ich unter „Immutable“ verstehe: Ich ändere nie das laufende System, ich ändere die Beschreibung und lasse das System daraus neu bauen, alles lokal auf der Maschine.
Das Gerät: GPD MicroPC 2⌗
Der MicroPC 2 ist ein Mini-Laptop mit Daumentastatur für Admins, Techniker und IT-Profis. Die wichtigsten Eckdaten (je nach Variante mit Intel N250 oder N300):
| Merkmal | Wert |
|---|---|
| Display | 7″ Full HD (1920×1080), Touch, um 180° drehbar (Tablet-Modus) |
| CPU | Intel N250 bzw. N300 (sparsamer 4-Kern-Chip bzw. 8-Kern-Chip der N-Serie) |
| RAM | 16 GB LPDDR5 |
| Speicher | 4 TB NVMe (Samsung M.2 2280) |
| Anschlüsse | 2× USB-C (Power Delivery, DisplayPort 1.4), 2× USB-A, HDMI 2.1, 2,5-GbE-Ethernet, microSD |
| Funk | WLAN 6, Bluetooth 5 |
Die serielle RS-232-Schnittstelle des ersten MicroPC gibt es leider nicht mehr. Dafür ist der Anschlussmix für ein Gerät dieser Größe weiterhin außergewöhnlich – genau das macht den MicroPC zum „Profi“-Gerät, das man trotzdem in die Jackentasche steckt.
Was die Konfiguration leistet⌗
Die angehängte configuration.nix ist primär für ein Notebook/Convertible mit Stift und Touch gebaut. Die wichtigsten Bausteine:
| Bereich | Umsetzung |
|---|---|
| Desktop | GDM mit Phosh (Squeekboard) als Standardsitzung, GNOME als vollwertige Rückfallebene |
| Apps | ausschließlich Flatpak (Flathub), nur auf User-Ebene – systemweite Installationen werden per Polkit gesperrt |
| Verschlüsselung | LUKS-Vollverschlüsselung, Entsperren per FIDO2-Stick (Passphrase bleibt als Notfall-Slot) |
| Virtualisierung | virt-manager (KVM/QEMU mit virtuellem TPM), Waydroid für Android-Apps, Podman + Distrobox |
| Mobil | power-profiles-daemon, thermald, Sensoren (iio) für Auto-Rotation, zram-Swap, TRIM |
| Eingabe | Touch und Stift über libinput/libwacom, Neo2-Layout systemweit (auch in der Konsole und im initrd) |
| Dateimanager | Vorschaubilder für (fast) alles: Videos, EPUB, Fonts, Office, 3D-Modelle, HEIC, RAW, SVG, WebP |
| Nix selbst | Flakes aktiviert, automatische Garbage Collection (wöchentlich, älter als 30 Tage), Store-Optimierung |
| Boot | systemd-boot (max. 10 Generationen), Plymouth, aktueller Kernel |
Installation Schritt für Schritt⌗
Der Weg besteht aus zwei Phasen: Erst installiert der
grafische NixOS-Installer (GNOME)
ein Basissystem samt Verschlüsselung und Partitionierung. Danach wird die eigene configuration.nix eingespielt und das System per Rebuild darauf umgestellt.
0. Voraussetzungen⌗
- ein USB-Stick (mind. 8 GB)
- eine funktionierende Internetverbindung (WLAN reicht)
- Backup aller Daten auf dem Gerät – die Platte wird komplett gelöscht
- optional: ein FIDO2-Stick (später für das LUKS-Entsperren)
- die
configuration.nixaus dem Anhang auf einem zweiten USB-Stick oder in einem Git-Repository
1. ISO herunterladen und auf USB schreiben⌗
Von nixos.org/download die Graphical ISO image (GNOME) laden. Unter Linux:
# Gerätenamen mit lsblk prüfen – das falsche Gerät zu überschreiben ist unwiederbringlich!
lsblk
sudo dd if=nixos-graphical-*.iso of=/dev/sdX bs=4M status=progress conv=fsync
Alternativ gehen Fedora Media Writer, balenaEtcher oder gnome-disks („Laufwerks-Abbild wiederherstellen“).
2. Vom Stick booten⌗
Den MicroPC 2 mit eingestecktem Stick starten und über das Boot-Menü der Firmware den USB-Stick wählen. Falls der Stick nicht startet: im UEFI Secure Boot deaktivieren, denn das NixOS-Installationsabbild ist, glaube ich, nicht dafür signiert.
Der Installer startet in einer Live-GNOME-Sitzung. Da das Panel hochkant eingebaut ist, kann das Bild zunächst gedreht erscheinen – unter Einstellungen → Anzeigen lässt sich die Ausrichtung korrigieren. Mit einem externen Bildschirm (HDMI oder USB-C) geht die Installation natürlich auch.
3. WLAN verbinden und Installer starten⌗
Zuerst das WLAN über das Netzwerk-Menü verbinden, dann den Calamares-Installer („NixOS installieren“) starten.
4. Im Installer: die richtigen Entscheidungen⌗
| Schritt | Empfehlung |
|---|---|
| Sprache / Region | Deutsch, Europe/Berlin |
| Tastaturlayout | Deutsch (Neo 2) – die spätere Config setzt das ohnehin systemweit |
| Benutzer | Login-Name notieren: Er muss später mit benutzer in der Config übereinstimmen |
| Rechnername | Muss zu rechnername in der Config passen (oder die Config anpassen) |
| Desktop | GNOME wählen |
| Unfreie Software | Erlauben (u. a. Firmware-Blobs; die Config setzt allowUnfree ohnehin) |
| Partitionierung | Festplatte löschen, EFI-Systempartition (UEFI) – und „Datenträger verschlüsseln“ mit einer starken Passphrase aktivieren |
| Swap | Kein Swap nötig; die Config nutzt zram |
Die Passphrase ist später der Notfall-Schlüssel, auch wenn das Entsperren im Alltag per FIDO2-Stick laufen soll. Gut aufbewahren!
Installation starten, abwarten, neu starten, USB-Stick abziehen. Nach der Passphrase-Eingabe im Bootvorgang landet man im frischen GNOME-System.
5. Daten der Installation übernehmen⌗
Bevor die eigene Config eingespielt wird, drei Werte aus der frischen Installation ablesen. Das ist der wichtigste Schritt, damit der Rebuild ohne Überraschungen durchläuft:
# 1) UUID der LUKS-Partition (steht im vom Installer erzeugten hardware-configuration.nix)
grep -A3 luks /etc/nixos/hardware-configuration.nix
# 2) stateVersion der Installation
grep stateVersion /etc/nixos/configuration.nix
# 3) Benutzername und Hostname
whoami
hostname
In der Config oben im let-Block eintragen:
benutzer = "dein-benutzername"; # exakt der Login-Name aus dem Installer
rechnername = "nixos";
luksUuid = "DEINE-LUKS-UUID"; # aus hardware-configuration.nix
Und am Ende der Datei system.stateVersion auf den Wert der Installation setzen. Die stateVersion darf nicht „aufgefrischt“ werden – sie beschreibt, mit welchem Release die Daten und Dienste auf deinem System ursprünglich angelegt wurden.
Achtung: Weicht
benutzervom Installer-Benutzer ab, legt NixOS einen zweiten Benutzer an, statt den bestehenden zu übernehmen. Ebenso muss der Gerätenameluks-<UUID>exakt zum bestehenden Eintrag passen, sonst findet das initrd die verschlüsselte Platte nicht.
6. Eigene Config einspielen⌗
Die Originaldatei sichern und durch die eigene ersetzen. Die hardware-configuration.nix bleibt unangetastet – sie wird von der Config importiert und enthält Dateisysteme und Kernelmodule des Geräts.
sudo cp /etc/nixos/configuration.nix /etc/nixos/configuration.nix.orig
sudo cp ~/Downloads/configuration.nix /etc/nixos/configuration.nix
Wer seine Config lieber versioniert, legt sie in ein Git-Repository und verlinkt oder kopiert sie von dort nach /etc/nixos/.
7. Rebuild⌗
sudo nixos-rebuild switch
Beim ersten Mal lädt Nix sehr viel aus dem Binary-Cache (Phosh, Kernel, Thumbnailer, Waydroid, libvirt …). Das dauert je nach Verbindung eine Weile, auf dem sparsamen Prozessor sollte es aber überwiegend ein Download-, kein Kompiliervorgang sein.
Wer vorsichtig sein will, probiert die Config zuerst, ohne sie zum Boot-Eintrag zu machen:
sudo nixos-rebuild test # aktiviert die Config, ändert aber nicht den Bootloader
sudo nixos-rebuild switch # wenn alles passt: dauerhaft übernehmen
Danach neu starten. Auf dem Anmeldebildschirm ist Phosh vorausgewählt; über das Zahnrad lässt sich jederzeit auf GNOME umschalten.
Nach dem ersten Boot⌗
FIDO2-Stick für LUKS registrieren⌗
Die Config erwartet, dass der Stick ohne PIN, nur per Berühren bestätigt wird (die Config ist auf den Betrieb ohne PIN ausgelegt, weil im Tablet-Modus keine Tastatur zur Verfügung steht). Die Passphrase bleibt als Notfall-Keyslot erhalten:
sudo systemd-cryptenroll --fido2-device=auto \
--fido2-with-client-pin=no \
--fido2-with-user-presence=yes /dev/disk/by-uuid/DEINE-LUKS-UUID
# Prüfen
sudo systemd-cryptenroll /dev/disk/by-uuid/DEINE-LUKS-UUID
Ohne PIN kann jeder, der den Stick besitzt, die Platte entsperren. Wer das nicht möchte, nimmt --fido2-with-client-pin=yes bzw. einen Stick mit Fingerabdruck.
Für sudo und Polkit lässt sich der Stick ebenfalls als zweiter Faktor nutzen:
mkdir -p ~/.config/Yubico && pamu2fcfg > ~/.config/Yubico/u2f_keys
Flatpak-Apps installieren⌗
Flathub wird beim ersten Login automatisch als User-Remote angelegt. Installiert wird immer auf User-Ebene:
flatpak install --user flathub org.mozilla.firefox
flatpak install --user flathub com.github.xournalpp.xournalpp
flatpak install --user flathub com.github.tchx84.Flatseal # Berechtigungen
flatpak install --user flathub io.github.dvlab.boxbuddyrs # Distrobox-GUI
Distrobox⌗
Für alles, was nicht ins NixOS-Modell passt oder ein anderes Basissystem braucht:
distrobox create --name fedora --image registry.fedoraproject.org/fedora-toolbox:latest
distrobox enter fedora
Waydroid (Android-Apps)⌗
sudo waydroid init -s GAPPS -f # mit Google-Diensten
# oder
sudo waydroid init # ohne Google
waydroid session start &
waydroid show-full-ui
Vorschaubilder-Cache leeren⌗
Nach der ersten Aktivierung der Thumbnailer einmalig den alten Cache löschen:
rm -rf ~/.cache/thumbnails ~/.cache/thumbnails-bwrap-*
Alltag: Updates, Rollbacks, Aufräumen⌗
# System aktualisieren (Channel aktualisieren + neu bauen)
sudo nixos-rebuild switch --upgrade
# Zur vorherigen Generation zurück
sudo nixos-rebuild switch --rollback
# Vorhandene Generationen anzeigen
sudo nix-env --list-generations --profile /nix/var/nix/profiles/system
Zusätzlich kann man im systemd-boot-Menü beim Start direkt eine ältere Generation wählen – die Config hält bis zu 10 davon vor. Die automatische Garbage Collection räumt wöchentlich alles auf, was älter als 30 Tage ist.
Wer die Config wie Quellcode behandelt (und das sollte man), packt /etc/nixos in ein Git-Repository: jede Änderung nachvollziehbar, jedes Gerät mit einem git pull && sudo nixos-rebuild switch auf demselben Stand.
Stolpersteine⌗
- Flatpak ist nicht deklarativ. Das Basissystem ist reproduzierbar, die Liste der installierten Flatpak-Apps aber nicht – die steht nur in dieser Anleitung. Wer auch das festnageln will, schaut sich Projekte wie nix-flatpak an.
- Fingerabdruckleser:
services.fprintd.enable = true;steht in der Config mit dem Kommentar „falls vorhanden“. Mein MicroPC 2 hat keinen – die Zeile ist hier also entbehrlich. - Firmware:
fwupdist aktiviert, auf dem MicroPC 2 aber für BIOS-Updates nicht unterstützt. BIOS-Updates kommen von GPD als Windows-Programme. - Rotierter Bildschirm: Der Hochkant-Panel-Einbau kann Konsole und Bootmeldungen drehen. Hilfe schaffen Kernelparameter wie
video=<Connector>:panel_orientation=right_side_up(und ggf.fbcon=rotate:1) überboot.kernelParams; den Connector-Namen findest du unter/sys/class/drm/. Das sind Beispiele – die genauen Werte hängen vom Gerät ab. - Auto-Rotation:
hardware.sensor.iio.enableist gesetzt, ob der Lagesensor des Geräts sauber ankommt, sollte man aber selbst testen und nicht voraussetzen. - FIDO2 ohne PIN ist ein bewusster Kompromiss zwischen Komfort und Sicherheit (siehe oben).
- Benutzername und
stateVersionmüssen zur Installation passen (siehe Schritt 5). - TLP und
power-profiles-daemonnie gleichzeitig verwenden – die Config nutzt denpower-profiles-daemon, den GNOME und Phosh ohnehin ansprechen.
Fazit⌗
NixOS auf dem GPD MicroPC 2 verbindet, was ich suche: ein System, das sich aus einer Datei neu aufbauen lässt, mit aktuellem Kernel und aktuellem Desktop, verschlüsselt und per FIDO2 entsperrbar, mit Touch-tauglicher Shell (Phosh) und vollem GNOME als Rückfallebene. Dazu VMs, Container und Android-Apps für den Profi-Alltag, ohne die Basis zu verunreinigen – alles Veränderliche liegt in Flatpaks und Containern, alles Systemische in der Config.
Wenn etwas kaputtgeht, ist der Weg zurück ein Neustart. Und wenn der MicroPC irgendwann ersetzt wird, ist das neue Gerät eine Installation, eine kopierte Datei und ein nixos-rebuild switch entfernt.
Anhang: die komplette configuration.nix⌗
Persönliche Angaben (Benutzername, LUKS-UUID, Klarname) sind durch Platzhalter ersetzt. Vor dem Rebuild die Werte im let-Block anpassen und system.stateVersion an die eigene Installation angleichen.
# ╔══════════════════════════════════════════════════════════════════════════╗
# ║ NixOS-Konfiguration – Notebook / Convertible mit Stift ║
# ║ ║
# ║ • Phosh (Squeekboard) als Standard-Sitzung, GNOME als Rückfallebene ║
# ║ • Anwendungen ausschließlich als Flatpak (Flathub, nur User-Ebene) ║
# ║ • LUKS-Vollverschlüsselung, Entsperren per FIDO2-Stick ║
# ║ • virt-manager, Waydroid, Podman + Distrobox ║
# ║ • Stifteingabe, Touch, Auto-Rotation, Notebook-Energieverwaltung ║
# ║ • Vorschaubilder im Dateimanager für (fast) alles ║
# ║ ║
# ║ Angepasst an deine bestehende Installation (NixOS 26.05). ║
# ╚══════════════════════════════════════════════════════════════════════════╝
{ config, lib, pkgs, ... }:
let
# ── Hier anpassen ────────────────────────────────────────────────────────
benutzer = "dein-benutzername"; # Dein Login-Name (wie im Installer)
rechnername = "nixos"; # Hostname
zeitzone = "Europe/Berlin";
luksUuid = "DEINE-LUKS-UUID"; # deine LUKS-Partition
# Sitzung, die im Anmeldebildschirm vorausgewählt ist ("phosh" oder "gnome")
standardSitzung = "phosh";
# ─────────────────────────────────────────────────────────────────────────
# Phosh bringt seine .desktop-Datei nicht in jeder Version so mit, dass GDM
# sie als Sitzung erkennt. Wir registrieren sie deshalb selbst – dann taucht
# „Phosh“ sicher im Zahnrad-Menü des Anmeldebildschirms auf.
phoshSitzung = (pkgs.writeTextFile {
name = "phosh-sitzung";
destination = "/share/wayland-sessions/phosh.desktop";
text = ''
[Desktop Entry]
Name=Phosh
Comment=Mobile Shell mit Squeekboard
Exec=${pkgs.phosh}/bin/phosh-session
Type=Application
DesktopNames=Phosh;GNOME
'';
}).overrideAttrs (alt: {
passthru = (alt.passthru or { }) // { providedSessions = [ "phosh" ]; };
});
# Thumbnailer-Pakete: Was in deiner nixpkgs-Version nicht existiert, wird
# einfach übersprungen, statt den ganzen Rebuild abzubrechen.
thumbnailer = lib.filter (p: p != null) (map (name: pkgs.${name} or null) [
"ffmpegthumbnailer" # Videos
"gnome-epub-thumbnailer" # EPUB/MOBI-Cover
"gnome-font-viewer" # Schriftarten
"libgsf" # OOXML/ODF-Vorschau
"f3d" # 3D-Modelle (STL, OBJ, glTF …)
"libheif" # HEIC-Vorschau
"ghostscript" # PS/EPS/PDF-Rendering
"imagemagick" # Fallback-Konvertierung
"resvg" # SVG
"webp-pixbuf-loader" # WebP
"libopenraw" # RAW-Fotos (CR2, NEF, ARW …)
]);
in
{
imports = [
# Wird vom Installer erzeugt (nixos-generate-config). Enthält Dateisysteme,
# Kernelmodule und Hardware-Erkennung.
./hardware-configuration.nix
# Zusätzliches Bildformat für gdk-pixbuf (WebP).
# Wird nur gesetzt, wenn deine NixOS-Version die Option kennt.
({ options, ... }: {
config = lib.optionalAttrs (options.programs ? gdk-pixbuf) {
# Nur Pakete, die garantiert einen pixbuf-Loader mitbringen.
# (HEIC übernimmt der libheif-Thumbnailer weiter unten.)
programs.gdk-pixbuf.modulePackages = with pkgs; [
webp-pixbuf-loader
];
};
})
];
# ════════════════════════════════════════════════════════════════════════
# Nix selbst
# ════════════════════════════════════════════════════════════════════════
nix.settings = {
experimental-features = [ "nix-command" "flakes" ];
auto-optimise-store = true;
};
nix.gc = {
automatic = true;
dates = "weekly";
options = "--delete-older-than 30d";
};
nixpkgs.config.allowUnfree = true; # u. a. für Firmware-Blobs
# ════════════════════════════════════════════════════════════════════════
# Bootloader, Kernel & LUKS mit FIDO2
# ════════════════════════════════════════════════════════════════════════
boot.loader = {
systemd-boot = {
enable = true;
configurationLimit = 10; # /boot nicht mit alten Generationen füllen
};
efi.canTouchEfiVariables = true;
};
# Aktueller Kernel = beste Unterstützung für neue Notebooks, Touchscreens,
# Stifte (HID, Wacom, ELAN, N-Trig …) und Sensoren.
boot.kernelPackages = pkgs.linuxPackages_latest;
# systemd im initrd ist die Voraussetzung für FIDO2-Entsperrung
# (systemd-cryptenroll) und erlaubt auch PIN-Abfrage des Sticks.
boot.initrd.systemd.enable = true;
# USB-/HID-Module früh laden, damit der FIDO2-Stick im initrd erkannt wird.
boot.initrd.availableKernelModules = [
"usbhid" "hid_generic" "xhci_pci" "xhci_hcd" "usb_storage"
];
# Der Name muss zu deiner bestehenden Installation passen (nicht umbenennen!).
boot.initrd.luks.devices."luks-${luksUuid}" = {
device = "/dev/disk/by-uuid/${luksUuid}";
allowDiscards = true; # TRIM auf SSD (kleiner Sicherheits-Kompromiss)
crypttabExtraOpts = [
"fido2-device=auto" # FIDO2-Token automatisch suchen
"token-timeout=15" # nach 15 s auf Passphrase zurückfallen
];
};
# Ohne Tastatur gibt es keine PIN-Eingabe: Der Stick wird daher OHNE PIN
# eingerichtet und per Berühren (User Presence) bestätigt.
# Wichtig: Die Passphrase bleibt als Notfall-Keyslot erhalten!
# Stick einrichten: siehe Hinweise am Ende dieser Datei.
boot.plymouth.enable = true;
boot.consoleLogLevel = 0;
boot.initrd.verbose = false;
# ════════════════════════════════════════════════════════════════════════
# System-Grundlagen
# ════════════════════════════════════════════════════════════════════════
networking.hostName = rechnername;
networking.networkmanager.enable = true; # WLAN, Mobilfunk (ModemManager), VPN
networking.nftables.enable = true; # modernes Backend, gut für Waydroid/libvirt
time.timeZone = zeitzone;
i18n.defaultLocale = "de_DE.UTF-8";
i18n.supportedLocales = [ "de_DE.UTF-8/UTF-8" "en_US.UTF-8/UTF-8" ];
i18n.extraLocaleSettings = {
LC_ADDRESS = "de_DE.UTF-8";
LC_IDENTIFICATION = "de_DE.UTF-8";
LC_MEASUREMENT = "de_DE.UTF-8";
LC_MONETARY = "de_DE.UTF-8";
LC_NAME = "de_DE.UTF-8";
LC_NUMERIC = "de_DE.UTF-8";
LC_PAPER = "de_DE.UTF-8";
LC_TELEPHONE = "de_DE.UTF-8";
LC_TIME = "de_DE.UTF-8";
};
console = {
font = "Lat2-Terminus16";
keyMap = "neo"; # Neo2 auch auf der Konsole
earlySetup = true; # Layout schon im initrd (LUKS-Passphrase!)
};
# Neo2 systemweit: GDM, GNOME, Phosh/Phoc und XWayland lesen das hier.
services.xserver.xkb = {
layout = "de";
variant = "neo";
};
zramSwap.enable = true; # komprimierter Swap im RAM
services.fstrim.enable = true; # regelmäßiges TRIM
services.fwupd.enable = true; # Firmware-Updates (LVFS)
hardware.enableRedistributableFirmware = true;
# ════════════════════════════════════════════════════════════════════════
# Grafik, Audio, Bluetooth, Drucken
# ════════════════════════════════════════════════════════════════════════
hardware.graphics.enable = true;
# NVIDIA-Notebook? Dann etwa:
# services.xserver.videoDrivers = [ "nvidia" ];
# hardware.nvidia = { modesetting.enable = true; open = true;
# prime = { offload.enable = true; intelBusId = "PCI:0:2:0"; nvidiaBusId = "PCI:1:0:0"; }; };
services.pulseaudio.enable = false; # PipeWire ersetzt PulseAudio
security.rtkit.enable = true;
services.pipewire = {
enable = true;
alsa.enable = true;
alsa.support32Bit = true;
pulse.enable = true;
};
hardware.bluetooth = {
enable = true;
powerOnBoot = true;
};
services.printing = {
enable = true;
drivers = [ pkgs.gutenprint ];
};
services.avahi = { # Netzwerkdrucker automatisch finden
enable = true;
nssmdns4 = true;
openFirewall = true;
};
# ════════════════════════════════════════════════════════════════════════
# Notebook-Unterstützung: Energie, Touchpad, Sensoren
# ════════════════════════════════════════════════════════════════════════
services.power-profiles-daemon.enable = true; # Energiemodi (GNOME + Phosh nutzen das)
services.upower.enable = true; # Akkustand
services.thermald.enable = true;
# (TLP und power-profiles-daemon nicht gleichzeitig verwenden!)
services.logind.settings.Login = {
HandleLidSwitch = "suspend";
HandleLidSwitchExternalPower = "suspend";
HandlePowerKey = "suspend";
};
services.libinput = {
enable = true;
touchpad = {
tapping = true;
naturalScrolling = true;
disableWhileTyping = true;
clickMethod = "clickfinger";
};
};
# Lage-/Beschleunigungssensor, Umgebungslicht → Auto-Rotation, Auto-Helligkeit
hardware.sensor.iio.enable = true;
# Fingerabdruckleser (falls vorhanden, sonst auskommentiert lassen):
services.fprintd.enable = true;
# ════════════════════════════════════════════════════════════════════════
# Stifteingabe & Touchscreen
# ════════════════════════════════════════════════════════════════════════
# Unter Wayland erledigt libinput + libwacom die Stift-Unterstützung
# (Druckstufen, Radierer, Tasten, Neigung). Das GNOME-Wacom-Panel ist
# bereits in den Systemeinstellungen enthalten.
#
# Externe Zeichentabletts (Wacom, Huion, XP-Pen …) mit eigenem Treiber:
# hardware.opentabletdriver.enable = true;
#
# Microsoft-Surface / Intel-IPTS-Touchscreens mit Stift:
# services.iptsd.enable = true;
# (Für Surface-Geräte zusätzlich das Flake „nixos-hardware“ einbinden:
# nixos-hardware.nixosModules.microsoft-surface-<modell>)
# ════════════════════════════════════════════════════════════════════════
# Desktop: GDM + Phosh (Standard) + GNOME (Rückfallebene)
# ════════════════════════════════════════════════════════════════════════
services.displayManager = {
gdm.enable = true; # ab GNOME 50 immer Wayland
sessionPackages = [ phoshSitzung ];
defaultSession = standardSitzung;
};
# Vollwertiges GNOME „für alle Fälle“
services.desktopManager.gnome.enable = true;
# Aus deiner alten Config übernommen: XWayland sofort starten (bessere
# Kompatibilität mit X11-Apps). Das Phosh-Modul wird nicht mehr benutzt,
# also schreiben wir die Phoc-Konfiguration selbst.
environment.etc."phosh/phoc.ini".text = ''
[core]
xwayland=immediate
'';
# Phosh-Zubehör: Rückmeldung (Vibration/Sound), Anrufe, Tastatur
programs.feedbackd.enable = true; # Haptik & Töne für Phosh
programs.calls.enable = true; # GNOME Calls (falls Modem vorhanden)
environment.systemPackages = with pkgs; [
# ── Phosh-Kern ──
phosh
phoc # Wayland-Compositor von Phosh
squeekboard # Bildschirmtastatur für Phosh
phosh-mobile-settings # Einstellungen für Phosh/Squeekboard
# ── Werkzeuge, die kein Flatpak sein sollen ──
git
vim
wget
curl
distrobox # Container-Umgebungen (Ersatz für Toolbox)
gnome-software # Flatpak-Verwaltung per GUI
dconf-editor
] ++ thumbnailer;
# GNOME-Standardprogramme, die du nicht willst, kannst du hier ausschließen:
# environment.gnome.excludePackages = with pkgs; [ epiphany geary totem ];
programs.dconf.enable = true;
# Systemweite dconf-Voreinstellungen (jeder Benutzer kann sie überschreiben)
programs.dconf.profiles.user.databases = [{
settings = {
# Dateimanager: Vorschaubilder IMMER erzeugen – auch bei Netzwerkfreigaben
"org/gnome/nautilus/preferences" = {
show-image-thumbnails = "always";
thumbnail-limit = lib.gvariant.mkUint64 4096; # MB; große Dateien nicht überspringen
};
"org/gnome/nautilus/list-view" = {
use-tree-view = false;
};
# virt-manager verbindet sich automatisch mit dem System-libvirt
"org/virt-manager/virt-manager/connections" = {
autoconnect = [ "qemu:///system" ];
uris = [ "qemu:///system" ];
};
# Tastaturlayout Neo2 fest als Eingabequelle (GNOME und Phosh)
"org/gnome/desktop/input-sources" = {
sources = [ (lib.gvariant.mkTuple [ "xkb" "de+neo" ]) ];
xkb-options = lib.gvariant.mkEmptyArray lib.gvariant.type.string;
};
# Stift/Touch freundlich: Tipp-zum-Klicken am Touchpad
"org/gnome/desktop/peripherals/touchpad" = {
tap-to-click = true;
natural-scroll = true;
};
};
}];
# ════════════════════════════════════════════════════════════════════════
# Vorschaubilder (Thumbnails) im Dateimanager
# ════════════════════════════════════════════════════════════════════════
# Nautilus erzeugt Vorschauen über kleine Hilfsprogramme („Thumbnailer“).
# Jeder Thumbnailer muss installiert UND unter /share/thumbnailers
# auffindbar sein – dafür sorgt die pathsToLink-Zeile.
environment.pathsToLink = [ "/share/thumbnailers" ];
# Zusätzliche Bildformate für gdk-pixbuf (WebP, HEIC/HEIF, AVIF, JPEG XL …)
# (Die Thumbnailer-Pakete stehen oben in environment.systemPackages.)
# Hinweis: PDF-Vorschau liefert bereits GNOME selbst (Papers/Evince).
# Nach der ersten Aktivierung ggf. alten Cache löschen:
# rm -rf ~/.cache/thumbnails ~/.cache/thumbnails-bwrap-*
# ════════════════════════════════════════════════════════════════════════
# Flatpak – nur auf User-Ebene, Flathub als User-Remote
# ════════════════════════════════════════════════════════════════════════
services.flatpak.enable = true;
# Flathub beim ersten Login automatisch als USER-Remote anlegen.
# (Es wird absichtlich KEIN systemweites Remote eingerichtet.)
systemd.user.services.flathub-user-remote = {
description = "Flathub als User-Remote einrichten";
wantedBy = [ "default.target" ];
path = [ pkgs.flatpak ];
script = ''
flatpak remote-add --user --if-not-exists flathub \
https://dl.flathub.org/repo/flathub.flatpakrepo
'';
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
# Falls das Netzwerk beim Login noch nicht steht: später erneut versuchen
Restart = "on-failure";
RestartSec = "30s";
};
};
# Systemweite Flatpak-Installationen per Polkit verbieten, damit wirklich
# alles unter ~/.local/share/flatpak landet – auch über GNOME Software.
security.polkit.extraConfig = ''
polkit.addRule(function(action, subject) {
var verboten = [
"org.freedesktop.Flatpak.app-install",
"org.freedesktop.Flatpak.runtime-install",
"org.freedesktop.Flatpak.app-uninstall",
"org.freedesktop.Flatpak.runtime-uninstall",
"org.freedesktop.Flatpak.install-bundle",
"org.freedesktop.Flatpak.modify-repo",
"org.freedesktop.Flatpak.configure-remote"
];
if (verboten.indexOf(action.id) !== -1) {
return polkit.Result.NO;
}
});
'';
# Portale: Dateiauswahl, Screenshots, Drucken usw. für Flatpak-Apps
xdg.portal = {
enable = true;
extraPortals = [ pkgs.xdg-desktop-portal-gtk ];
};
# Systemschriften und -symbole für Flatpak-Apps sichtbar machen
fonts = {
fontDir.enable = true;
packages = with pkgs; [
noto-fonts
noto-fonts-cjk-sans
noto-fonts-color-emoji
liberation_ttf
inter
];
};
# ════════════════════════════════════════════════════════════════════════
# Virtualisierung: virt-manager, Waydroid, Podman/Distrobox
# ════════════════════════════════════════════════════════════════════════
# ── virt-manager (KVM/QEMU) ──
virtualisation.libvirtd = {
enable = true;
qemu = {
swtpm.enable = true; # virtuelles TPM (Windows 11!)
runAsRoot = false;
};
};
programs.virt-manager.enable = true;
virtualisation.spiceUSBRedirection.enable = true; # USB-Geräte an VMs durchreichen
# ── Waydroid (Android-Apps) ──
virtualisation.waydroid.enable = true;
# Erste Einrichtung nach dem Booten:
# sudo waydroid init -s GAPPS -f (mit Google-Diensten)
# sudo waydroid init (ohne Google)
# waydroid session start & ; waydroid show-full-ui
# ── Podman + Distrobox ──
virtualisation.podman = {
enable = true;
dockerCompat = true; # „docker“-Befehl leitet an Podman um
defaultNetwork.settings.dns_enabled = true;
};
# Firewall: Android- und VM-Netzwerke dürfen DHCP/DNS des Hosts nutzen
networking.firewall.trustedInterfaces = [ "waydroid0" "virbr0" ];
# ════════════════════════════════════════════════════════════════════════
# FIDO2 / U2F im laufenden System (sudo, Polkit)
# ════════════════════════════════════════════════════════════════════════
services.udev.packages = [ pkgs.libfido2 ]; # udev-Regeln für FIDO2-Sticks
services.pcscd.enable = true; # Smartcard-Dienst (YubiKey & Co.)
security.pam.u2f = {
enable = true;
control = "sufficient"; # Stick ODER Passwort genügt
settings.cue = true; # Hinweis „Bitte Stick berühren“
};
security.pam.services = {
sudo.u2fAuth = true;
polkit-1.u2fAuth = true;
};
# Schlüssel registrieren:
# mkdir -p ~/.config/Yubico && pamu2fcfg > ~/.config/Yubico/u2f_keys
# ════════════════════════════════════════════════════════════════════════
# Dienste für die Sitzungen
# ════════════════════════════════════════════════════════════════════════
services.gnome.gnome-keyring.enable = true;
services.gvfs.enable = true; # Netzwerkfreigaben, MTP, Papierkorb
services.gnome.localsearch.enable = true; # Dateisuche
services.gnome.tinysparql.enable = true;
# ════════════════════════════════════════════════════════════════════════
# Benutzer
# ════════════════════════════════════════════════════════════════════════
users.users.${benutzer} = {
isNormalUser = true;
description = "Dein Name";
extraGroups = [
"wheel" # sudo
"networkmanager"
"video"
"audio"
"input"
"libvirtd" # virt-manager ohne Root
"kvm"
"podman"
"dialout"
];
# initialPassword = "ändern!"; # nur beim allerersten Setup, danach `passwd`
};
# ════════════════════════════════════════════════════════════════════════
# Systemversion – bleibt wie bei deiner Installation. NICHT ändern!
# ════════════════════════════════════════════════════════════════════════
system.stateVersion = "26.05";
# ══════════════════════════════════════════════════════════════════════════
# EINRICHTUNGS-ANLEITUNG (nach dem ersten Boot)
# ══════════════════════════════════════════════════════════════════════════
#
# 1) FIDO2-Stick für LUKS registrieren (Passphrase bleibt als Backup):
# sudo systemd-cryptenroll --fido2-device=auto \
# --fido2-with-client-pin=no \
# --fido2-with-user-presence=yes /dev/disk/by-uuid/DEINE-LUKS-UUID
# (Ohne Tastatur keine PIN: Wer den Stick besitzt, kann entsperren.
# Alternative: Stick mit Fingerabdruck, z. B. YubiKey Bio.)
# Prüfen: sudo systemd-cryptenroll /dev/disk/by-uuid/DEINE-LUKS-UUID
# Zweiten Stick als Reserve ebenfalls registrieren!
#
# 2) Flatpak-Apps installieren (immer als User):
# flatpak install --user flathub org.mozilla.firefox
# flatpak install --user flathub com.github.flxzt.rnote # Stift-Notizen
# flatpak install --user flathub com.github.xournalpp.xournalpp
# flatpak install --user flathub com.github.tchx84.Flatseal # Rechte
# flatpak install --user flathub io.github.dvlab.boxbuddyrs # Distrobox-GUI
#
# 3) Distrobox:
# distrobox create --name fedora --image registry.fedoraproject.org/fedora-toolbox:latest
# distrobox enter fedora
#
# 4) Rebuild:
# sudo nixos-rebuild switch
# Bei Problemen mit Phosh im Anmeldebildschirm das Zahnrad → „GNOME“.
# ══════════════════════════════════════════════════════════════════════════
}