Build fehlgeschlagen ohne Logs: So erhalten Sie die Ausgabe
Wenn ein Build ohne Logs fehlschlägt, ist der Fehler vor dem eigentlichen Build aufgetreten. Erfahren Sie, an welchen vier Stellen das passiert, wie Sie sie unterscheiden und wie Sie aus jeder Phase Ausgaben erhalten.
„Build fehlgeschlagen.“ Kein Stack Trace, kein Compiler-Fehler, überhaupt keine Ausgabe. Ein Build, der ohne Logs fehlschlägt, ist die am wenigsten hilfreiche Meldung, die eine Plattform ausgeben kann. Meist steckt dahinter jedoch etwas Bestimmtes, das man verstehen sollte: Der Fehler ist vor dem Start des Prozesses aufgetreten, der die Logs erzeugt.
Ein Build besteht nicht aus einem einzigen Schritt. Es gibt vier Schritte, und jeder schlägt auf eine andere Weise fehl.
Die vier Phasen
1. Quellcode abrufen. Die Plattform klont Ihr Repository auf einem bestimmten Ref. 2. Build vorbereiten. Sie ermittelt, wie der Build ausgeführt werden soll – mit Dockerfile, Buildpack oder einem erkannten Framework. 3. Build ausführen. Ihre Befehle werden ausgeführt. Nur in dieser Phase entsteht die Ausgabe, die Sie erwarten. 4. Paketieren. Das Ergebnis wird in ein ausführbares Image umgewandelt.
Wenn überhaupt keine Logs vorhanden sind, ist der Fehler in Phase 1 oder 2 aufgetreten. Ihr Build wurde nie ausgeführt und konnte daher auch nichts ausgeben.
Phase 1: Ihr Code wurde nie abgerufen
Die Symptome sind völlige Stille und ein schneller Fehler – normalerweise innerhalb von fünfzehn Sekunden.
Häufige Ursachen, in dieser Reihenfolge:
- Der Branch existiert nicht. Ein Service ist für Deployments von
masterkonfiguriert, während das Repository inmainumbenannt wurde. Das schlägt sofort fehl und liefert kaum Informationen. - Der Zugriff wurde entzogen. Das Token oder die App-Installation, die letzten Monat noch funktioniert hat, wurde entfernt, oder das Repository wurde in eine Organisation verschoben, für die die Berechtigung nicht mehr gilt.
- Das Repository ist privat und die Verbindung ist abgelaufen. Der Ablauf ist derselbe wie oben: Die Plattform erhält einen 404 statt eines 403, weil Git-Provider dies für private Repositorys zurückgeben, auf die Sie keinen Zugriff haben.
- Ein Submodul kann nicht abgerufen werden. Das Haupt-Repository wird geklont, aber ein Submodul mit einer SSH-URL schlägt fehl, weil der Build-Umgebung dafür kein Schlüssel vorliegt.
Die schnelle Prüfung: Zeigt die Plattform für das fehlgeschlagene Deployment einen Commit-Hash an? Wenn nicht, wurde der Code nie abgerufen, und nichts in Ihrem Dockerfile ist relevant.
Phase 2: Die Plattform weiß nicht, wie sie den Build ausführen soll
Auch diese Phase bleibt still, weil noch kein Build-Befehl ausgewählt wurde.
- Kein Dockerfile am konfigurierten Speicherort. Ein
dockerfilePathverweist auf einen Pfad, der verschoben wurde. - Ein Monorepo ohne Root-Konfiguration. Die Plattform betrachtet das Repository-Root, während sich Ihr Service in
apps/apibefindet. - Die Erkennung hat nichts gefunden. Kein erkanntes Manifest, daher passte kein Buildpack.
- Ein Dockerfile, das nicht geparst werden kann. Ein Syntaxfehler in Zeile 1 führt zum Abbruch, bevor irgendein Layer ausgeführt wird.
Phase 3: Hier gibt es Logs
Wenn Sie eine teilweise Ausgabe sehen, die abrupt abbricht, befinden Sie sich in Phase 3. Die beiden häufigsten Ursachen sind dann Ressourcenprobleme und nicht der Code:
Nicht genügend Arbeitsspeicher. Ein Build, der vom OOM-Reaper beendet wird, kann dazu keine Meldung mehr ausgeben. Das Log bricht einfach mitten in einem Schritt ab. TypeScript-, webpack- und Vite-Builds in großen Codebasen sind davon regelmäßig betroffen. Ein Hinweis darauf ist, dass derselbe Commit auf Ihrem Laptop problemlos gebaut wird, weil dieser mehr Arbeitsspeicher als der Builder hat.
Timeout. Ein Build, der das Plattformlimit überschreitet, wird beendet. Dasselbe Symptom: Die Ausgabe bricht ab, statt regulär zu enden.
Beides sieht wie „keine Logs“ aus, wenn der Fehler früh genug auftritt.
Phase 4: Der Build war erfolgreich, kann aber nicht paketiert werden
Selten und eindeutig: Der Build war erfolgreich, aber das Artefakt ist fehlerhaft. Beispielsweise kann ein Image ohne CMD oder ENTRYPOINT, ein Architekturkonflikt oder ein Image vorliegen, das zu groß für das Plattformlimit ist.
Die Diagnose-Reihenfolge
# Gibt es einen Commit-Hash? Wenn nicht, Phase 1.
dockup deployments my-project/my-api --json
# Build-Logs des letzten Deployments streamen
dockup logs my-project/my-api --build --follow
# Der vollständige Datensatz einschließlich der Dauer jeder Phase
dockup status my-project/my-api --json
stageTimings in der letzten Ausgabe ist der schnellste Weg, den Fehler zu lokalisieren. Ein Deployment, das 0,4 Sekunden mit dem Klonen verbracht hat und anschließend in Phase 1 als fehlgeschlagen beendet wurde, ist eindeutig. Eines, das neunzig Sekunden mit dem Build verbracht hat und dann abbrach, weist auf ein Problem in Phase 3 hin – höchstwahrscheinlich auf den Arbeitsspeicher.
Ausgabe erhalten, wenn keine vorhanden ist
Drei Techniken, nach steigendem Aufwand:
Die Einschränkung lokal reproduzieren. Nicht „Funktioniert der Build auf meinem Rechner?“ – bauen Sie ihn mit demselben Arbeitsspeicher, der dem Builder zur Verfügung steht:
docker build --memory=2g --memory-swap=2g -t test .
Wenn sich der Fehler damit reproduzieren lässt, haben Sie die Ursache gefunden. Es handelt sich um ein Speicherproblem und nicht um etwas Mysteriöses.
Mehr Ausgabe in Ihrem Build aktivieren. Die meisten Build-Tools sind standardmäßig zurückhaltend bei dem Problem, das sie gleich zum Absturz bringt.
# Fortschritt ausgeben, damit ein abgeschnittenes Log zeigt, wo der Abbruch erfolgte
RUN npm ci --loglevel verbose
RUN NODE_OPTIONS="--max-old-space-size=3072" npm run build
Allein diese NODE_OPTIONS-Zeile ist einen Versuch wert – ein Node-Build, der still beendet wird, scheitert sehr häufig an einem Heap-Limit. Eine Erhöhung des Limits behebt Builds, die überhaupt keine Diagnose ausgegeben haben.
Das Dockerfile per Bisecting untersuchen. Kommentieren Sie alles nach dem fehlschlagenden Schritt aus und fügen Sie RUN echo "reached step N"-Marker ein. Grob, aber wirksam, wenn nichts anderes hilft.
Was diese Problemklasse reduziert
Zwei Dinge sind wichtiger als jede Debugging-Technik.
Logs streamen statt zusammenfassen. Wenn die Ausgabe erst nach Abschluss eines Builds angezeigt wird, liefert ein beendeter Build nichts, weil die Zusammenfassung am Ende geschrieben wird. Beim Streaming bleibt das Log erhalten, das bis zum Abbruch erzeugt wurde.
dockup logs my-project/my-api --build --follow
Benannte und zeitlich erfasste Phasen. „Build fehlgeschlagen“ ist eine Information von einem Bit. „Klonen: 0,4 s, Build: nach 94 s fehlgeschlagen“ reicht aus, um drei der vier oben genannten Ursachen auszuschließen, ohne weitere Details lesen zu müssen.
Häufig gestellte Fragen
Warum erzeugt mein Build überhaupt keine Logs? Weil er fehlschlug, bevor Ihre Build-Befehle ausgeführt wurden – normalerweise beim Abrufen des Quellcodes oder beim Ermitteln des Build-Verfahrens. Keine dieser Phasen erzeugt eine Build-Ausgabe.
Warum funktioniert der Build lokal, aber nicht auf der Plattform?
Meistens liegt es am Arbeitsspeicher. Ihr Rechner hat mehr davon als der Builder. Reproduzieren Sie den Build mit docker build --memory=2g, bevor Sie an anderer Stelle suchen.
Was bedeutet ein Log, das mitten in einem Schritt abbricht? Der Prozess wurde beendet, statt regulär zu beenden. Nicht genügend Arbeitsspeicher oder ein Build-Timeout sind die beiden wahrscheinlichsten Ursachen. Der OOM-Killer gibt dem Prozess keine Gelegenheit, den Grund selbst zu erklären.
Brauche ich ein Dockerfile? Nicht unbedingt – Plattformen können gängige Projekttypen erkennen und ohne eines davon bauen. Wenn die Erkennung jedoch fehlschlägt, führt das selbst zu einem stillen Fehler ohne Logs. Ein explizites Dockerfile beseitigt daher eine ganze Klasse von Unklarheiten.
