devenv-Services debuggen: wenn der Process-Manager grün zeigt, aber nichts läuft

devenvNixDebuggingDeveloper ExperienceProcess Management

devenv up ist grün. Vier Prozesse, alle ready, ein aufgeräumtes Dashboard. Und deine App funktioniert trotzdem nicht.

Diese Lücke — zwischen dem, was der Process-Manager meldet, und dem, was tatsächlich wahr ist — ist der Ort, an dem die meiste Zeit eines Tages verschwindet. Ich habe einen Nachmittag damit verbracht, eine absichtlich kaputte Sandbox zu bauen (eine Node-API, einen Python-Worker, Postgres und Redis, allesamt über devenv up verdrahtet) und sie dann auf fünf verschiedene Arten brechen zu lassen, um zu kartieren, wo die Wahrheit eigentlich liegt, wenn devenv dich anlügt. Das hier ist der Leitfaden, den ich mir gewünscht hätte.

Es beginnt mit einer Methode, das Kaputte zu kategorisieren, denn welchen Fix du greifst, hängt vollständig davon ab, welche Art von kaputt du vor dir hast.

Die vier Arten von Drift

Fast jedes „gestern lief es noch, ich schwöre, ich habe nichts geändert"-Versagen ist Drift: Die laufende Realität ist von der deklarierten Konfiguration abgewandert. Es gibt vier Geschmacksrichtungen, und sie zu benennen ist die halbe Miete.

Daten-Drift. Die Config ist korrekt, der Prozess ist gesund, aber der State ist falsch. In meiner Sandbox: Eine Datenbank wurde der App unter den Füßen weggenannt, und jeder Request lieferte database "app" does not exist. Der Service lief. Die Daten lagen nicht dort, wo der Service sie erwartete. devenvs initialDatabases läuft nur beim ersten Cluster-Init — es ist initial, nicht ensured — also stellte nichts sie wieder her.

Environment-Drift. Der deklarierte Toolchain und der installierte sind sich uneinig. Ich habe ein Python-Paket von Hand deinstalliert; requirements.txt führte es weiterhin auf, aber das venv hatte es nicht mehr. Der Worker geriet in einen Crash-Loop mit ModuleNotFoundError. Die Deklaration war ehrlich; die Realität war verrottet.

Config-Drift. Die Config, die du liest, ist nicht die Config, die läuft. Eine devenv.local.nix — automatisch importiert, standardmäßig git-ignoriert — enthielt env.PORT = lib.mkForce "3001". git diff war sauber. Die Datei war für jedes Tool unsichtbar, das die Versionskontrolle respektiert, und sie gewann den Merge stillschweigend.

Cache-Drift. Die fieseste. Die Config evaluiert korrekt und der laufende Prozess widerspricht ihr, weil eine veraltete Evaluation in eine Derivation eingebacken und gecacht wurde. Mehr dazu in einem eigenen Beitrag — es stellte sich als echter devenv-Bug heraus. Für den Moment reicht es zu wissen, dass es die Kategorie gibt, denn wenn nicht, löschst du dein ganzes State-Verzeichnis und das Problem ist immer noch da.

Sobald du den Drift benennen kannst, greifst du zum passenden Werkzeug.

Die Werkzeuge

Prozess-Logs liegen auf der Platte. Die TUI scrollt. Dein Crash wartet nicht, bis du gerade hinschaust. Jeder Prozess schreibt hierhin:

.devenv/run/processes/logs/<name>.stdout.log
.devenv/run/processes/logs/<name>.stderr.log

Das ist der einzelne wertvollste Pfad im gesamten .devenv-Baum. Wenn ein Prozess in gave_up ist und die TUI weitergezogen ist, liegt die Sterbeurkunde immer noch in <name>.stderr.log. tail -f darauf für einen Live-Stream — devenv processes logs <name> hat kein --follow, also ist die rohe Datei dein Freund.

Das devenv processes-CLI spiegelt die TUI. list, status <name>, logs <name> --stderr -n 500, start, stop, restart, down. Alle drei Kontrolloberflächen — TUI, CLI und (siehe nächster Beitrag) der MCP-Server — sprechen über .devenv/run/processes/native.sock mit demselben Manager. Drei Türen, ein Haus. Die eine, die man sich für Scripts und CI merken sollte, ist devenv processes wait: Es blockiert, bis jeder Probe grün ist, und verabschiedet damit sleep 10 für immer aus deinem Test-Setup.

devenv eval ist ein Röntgenbild der finalen Config. Das ist das Werkzeug, das Config-Drift-Diskussionen beendet. Es gibt den vollständig gemergten, vollständig evaluierten Wert jeder Option aus, nach jedem Import und Override:

$ devenv eval env.PORT
{ "env.PORT": "3001" }

Wenn devenv.nix 3000 sagt und das hier 3001, hast du kein Laufzeitproblem — du hast ein Config-Problem, und jetzt suchst du die Datei, die 3001 geschrieben hat. (Erster Zug, wenn ein Config-Rätsel auftaucht: ls *.nix. Die Schattendatei liegt meist direkt da.)

lsof beantwortet „wem gehört dieser Port?" Wenn ein Service sich leise verlagert — devenv weist standardmäßig den nächsten freien Port zu, falls einer belegt ist — fängst du das mit lsof ab:

$ lsof -i :6379 -i :5432 -i :3000

Ich habe es mir zur Disziplin gemacht: vor devenv up zu prüfen, dass die Ports tatsächlich frei sind. Ein Neustart-Reflex ist Beweisvernichtung; eine sterile Port-Liste ist Beweis.

Lies Nix-Fehlerwände von unten. Eine fehlgeschlagene Evaluation druckt einen Bildschirm voll … while evaluating …-Kontext. Es ist ein Stack-Trace; die eigentliche Meldung steht ganz unten:

$ devenv shell 2>&1 | tail -25

devenvs eigene Fehler liefern dir häufig den exakten Fix. Der, der an mir vorbeiscrollte, sagte, vollständig: To use 'languages.python.version', run: devenv inputs add nixpkgs-python …. Die Antwort steckte die ganze Zeit im Fehler.

Der Spickzettel

Wenn etwas kaputt ist, ordne das Symptom dem ersten Ort zum Nachschauen zu:

SymptomDriftZuerst nachschauen
Service läuft, falscher/fehlender StateDatenpsql/redis-cli direkt in den Service
Crash-Loop beim StartEnvironmentprocesses logs <name> --stderr
Config passt nicht zur DateiConfigdevenv eval <option>, dann ls *.nix
eval stimmt, Laufzeit ist falschCacheStore-Pfade vergleichen (nächste Stufe)
Service hat still den Port gewechseltlsof -i :PORT

Nichts davon erfordert tiefes Nix-Wissen. Es erfordert zu wissen, dass das ready des Process-Managers eine Behauptung ist, kein Beweis — und die fünf Orte zu kennen, an denen der Beweis tatsächlich liegt.

Die Disziplin unter alldem ist eine Regel: kein Fix vor der Root Cause. Ein Rateschuss, der zufällig funktioniert, lehrt dich nichts und hinterlässt Komplexität. Zuerst Evidenz zu sammeln ist fast immer günstiger als drei falsche Rateschüsse. Die Werkzeuge oben sind nur die schnellsten Wege zu dieser Evidenz.

Quellen

Als Nächstes: dieses gesamte Werkzeug einem KI-Assistenten in die Hand geben, damit er die Logs selbst zieht und an den Prozessen rüttelt.

Alle Artikel