Apple beschreibt die Verwaltung zusätzlicher Xcode-Komponenten und Simulator-Runtimes als getrennte Aufgaben mit eigenen unterstützten Verwaltungswegen (Dokumentation zur Xcode-Komponentenverwaltung). Deshalb gilt bei Xcode No space left on device im Jahr 2026: Zuerst den Schreibvorgang stoppen, dann die fünf Verursacherbereiche Arbeitsbereich, DerivedData, Simulator, Archive und Paketmanager-Caches getrennt belegen. Erst danach dürfen nachweislich nicht mehr verwendete, reproduzierbare Daten gelöscht werden. Wenn der Speicher trotz einer kontrollierten Bereinigung unter normaler Last erneut vollläuft, sind Aufbewahrung, Aufgabentrennung oder die Kapazität des Remote-Mac anzupassen; wiederholtes Löschen des gesamten Datenträgers ist keine Reparatur.

Für wen dieser Ablauf gedacht ist: Für den Bereitschaftsdienst, der einen abgebrochenen Build mit möglichst wenig Datenverlust wieder aufnehmen muss. Für DevOps-Verantwortliche, die einen gemeinsam genutzten Remote-Mac-Runner verwalten. Und für Plattformingenieure, die entscheiden müssen, ob Bereinigung, Neuaufbau oder eine größere Mac-Ressource die richtige Maßnahme ist.

01

Die ersten 30 Minuten: Schreibvorgang einfrieren und Beweise sichern

Ein Logeintrag wie No space left on device beantwortet nicht, welcher Prozess den Speicher belegt hat. Der Fehler kann aus einem Arbeitsverzeichnis, einem temporären Export, einem Simulator-Gerät, einem Cache oder einem parallelen Auftrag stammen. Daher sollte der Bereitschaftsdienst nicht sofort rm -rf gegen ein gesamtes Entwicklungsverzeichnis ausführen und auch keinen Runner neu aufsetzen.

Zuerst werden weitere Builds, Tests und Archive für den betroffenen Knoten angehalten. Ein laufender Prozess kann Dateien während der Analyse weiter vergrößern oder nach einer Bereinigung erneut anlegen. Die Ausführungskonfiguration muss dabei festgehalten werden: Benutzerkonto, Arbeitsverzeichnis, aktiver Xcode-Pfad, Commit, Build-Konfiguration, Zielgerät und parallele Jobs.

Die erste Bestandsaufnahme kann mit allgemeinen Systembefehlen erfolgen:

date
hostname
id
df -h /
df -i /
du -sh "$HOME"/* 2>/dev/null | sort -h | tail -n 20
ps auxww | grep -E 'xcodebuild|simctl|swift|clang|codesign' | grep -v grep

Die Ausgabe wird zusammen mit dem ersten gültigen Fehler in der Störung gespeichert. df -h zeigt den verfügbaren Speicher des Dateisystems; df -i prüft zusätzlich, ob nicht die Anzahl der verfügbaren Dateieinträge erschöpft ist. Ein großer freier Speicher bei gleichzeitig erschöpften Inodes führt zu einer anderen Diagnose als ein vollständig belegtes Volume.

Der aktive Xcode- und SDK-Kontext wird nicht aus einer vermuteten Standardinstallation abgeleitet:

xcode-select -p
xcodebuild -version
xcodebuild -showsdks
xcrun simctl list

Die verfügbaren Optionen und das Verhalten dieser Werkzeuge müssen auf dem Zielsystem mit xcodebuild -help, xcrun simctl help und den lokalen Manpages geprüft werden. Apple beschreibt die Xcode-Befehlszeilenwerkzeuge und ihre Verwendung in der Referenz für Xcode-Command-Line-Tools.

Prüfbereich Was jetzt festgehalten wird Was nicht voreilig gelöscht wird
Dateisystem Freier Speicher, Inodes, Mountpoint und Zeitpunkt Systemverzeichnisse und unbekannte Volumes
Build-Prozess Auftrag, Commit, Benutzerkonto, aktive Prozesse Noch laufende Arbeitsverzeichnisse
Arbeitsbereich Quellcode, temporäre Dateien, doppelte Checkouts Nicht veröffentlichte Änderungen
Testumgebung Benötigte Runtime, Geräteinstanzen, Testdaten Runtime des aktuellen Testmatrix-Ziels
Release Archive, Exporte, Symbole, Signaturmaterial Noch nicht ausgelieferte Artefakte und Schlüssel

Die folgende Tabelle ordnet die fünf Bereiche nach Risiko und Zuständigkeit. Sie ist keine Freigabe zum pauschalen Löschen.

Datenklasse Typischer Eigentümer Reproduzierbar? Vor einer Bereinigung erforderlicher Nachweis
Arbeitsbereich und temporäre Build-Ausgaben Bereitschaftsdienst Meist teilweise Auftrag gestoppt, Commit und Parameter gesichert
DerivedData Build-Wartung Häufig, aber nicht kostenlos Kein paralleler Auftrag verwendet den Pfad
Paketmanager- und Tool-Caches Build-Wartung In der Regel Cache-Zuordnung und erwartete Neuauflösung bekannt
Simulator-Geräte und Testdaten Testverantwortlicher Nur teilweise Benötigte Runtime und Geräteinstanz identifiziert
.xcarchive, Export und Symbole Release-Verantwortlicher Nicht als Liefernachweis Status, Aufbewahrung und Upload geprüft

Achtung: Eine erfolgreiche Rückgabe von xcodebuild nach der Bereinigung beweist noch nicht, dass die Pipeline wieder stabil ist. Erst ein sauberer Build, ein zweiter Build mit Cache-Wiederverwendung und der tatsächlich benötigte Test- oder Releasepfad liefern eine belastbare Freigabe.

02

Bereitschaftsdienst: Arbeitsbereich und einmaligen Build wiederherstellen

Der erste Verantwortungsbereich ist die Wiederaufnahme eines einzelnen fehlgeschlagenen Auftrags. Dazu werden alle Arbeitsverzeichnisse des betroffenen Kontos und die vom Runner verwendeten temporären Pfade geprüft. Platzhalter wie <CI_ROOT>, <PROJEKT> und <JOB_ID> müssen durch die Werte aus der Runner-Konfiguration ersetzt werden; feste Pfade dürfen nicht aus einem fremden Knoten übernommen werden.

du -sh <CI_ROOT>/<PROJEKT> 2>/dev/null
find <CI_ROOT> -maxdepth 3 -type d -name '<JOB_ID>*' -print
find <CI_ROOT> -type f \( -name '*.xcarchive' -o -name '*.ipa' -o -name '*.dSYM.zip' \) -print

Danach werden drei Gruppen gebildet:

  1. Quellcode, Konfigurationsdateien und nicht veröffentlichte Änderungen bleiben erhalten.
  2. Abgebrochene, eindeutig zuordenbare Zwischenprodukte dürfen nach Prüfung entfernt werden.
  3. Archive, Exporte, Symboldateien und Diagnoseprotokolle werden nur nach Release- oder Incident-Freigabe verschoben oder gelöscht.

Wenn ein doppelter Checkout denselben Commit enthält, ist nicht die bloße Namensähnlichkeit ausreichend. Zu prüfen sind Branch, lokale Änderungen, Submodule, generierte Konfigurationsdateien und der Status des zugehörigen Jobs. Die Löschung eines vermeintlich alten Verzeichnisses kann sonst die einzige reproduzierbare Eingabe des fehlgeschlagenen Laufs entfernen.

Nach der Freigabe wird mit demselben Commit und denselben Build-Parametern getestet. Ein verkürzter Test mit einer anderen Konfiguration ist nur eine Diagnose, keine Wiederherstellung:

xcodebuild \
  -workspace <ARBEITSBEREICH>.xcworkspace \
  -scheme <SCHEME> \
  -configuration <KONFIGURATION> \
  -destination '<ZIEL>' \
  -derivedDataPath <DERIVED_DATA_PFAD> \
  build

Wenn der freie Speicher unmittelbar wieder sinkt, stoppt der Bereitschaftsdienst weitere Wiederholungen. Die Prozessliste, die vorherige df-Aufnahme, die neue Speicheraufnahme und die zuletzt erzeugten Dateien werden an die Build-Wartung übergeben. Wiederholte Builds verschärfen in dieser Situation nur die Beweislage und können weitere Archive oder temporäre Daten erzeugen.

03

Build-Wartung: DerivedData und Paketmanager-Caches kontrollieren

DerivedData kann in einer Remote-Mac-CI gelöscht werden, aber nicht als blinder Standardbefehl. Der tatsächliche Ort hängt vom aktiven Xcode, vom Benutzerkonto und vom Parameter -derivedDataPath ab. Ein Auftrag kann also sowohl die Standardablage als auch einen ausdrücklich konfigurierten CI-Pfad verwenden.

Der Wartungsverantwortliche sucht deshalb zuerst nach der vom Job verwendeten Variable oder dem konkreten Parameter. Danach wird geprüft, ob noch ein Prozess auf den Inhalt zugreift:

pgrep -alf 'xcodebuild|swift|clang|SourcePackages'
du -sh <DERIVED_DATA_PFAD> 2>/dev/null
find <DERIVED_DATA_PFAD> -maxdepth 2 -type d -print 2>/dev/null | head -n 40

Nur ein gestoppter Auftrag, eine gesicherte Build-Konfiguration und ein eindeutig zugeordneter Pfad erlauben eine Bereinigung. Die Entfernung von DerivedData kann eine erneute Indexierung, Paketauflösung oder vollständige Kompilierung auslösen. Sie kann den akuten Platzmangel lösen, aber den nächsten Lauf zunächst verlängern; deshalb wird nicht allein die erfolgreiche Löschoperation bewertet.

Paketmanager-Caches werden getrennt von DerivedData behandelt. Zu prüfen sind Besitzer, letzter Zugriff, Projektzuordnung und die Frage, ob ein anderer Auftrag dieselben Daten nutzt. Ein gemeinsamer Cache kann wertvoll sein, während ein veralteter, projektbezogener Cache nur noch Platz bindet. Das gilt ebenso für lokale Tool-Caches und heruntergeladene Abhängigkeiten.

Für die Nachprüfung sind mindestens zwei Läufe erforderlich:

df -h /
# 1. sauberer Build mit gesichertem Commit
xcodebuild <DIESELBEN_PARAMETER_WIE_IM_FEHLERFALL>

# 2. gleicher Build zur Prüfung der Wiederverwendung
xcodebuild <DIESELBEN_PARAMETER_WIE_IM_ERSTEN_LAUF>

df -h /

Der erste Lauf muss die Pipeline funktional wiederherstellen. Der zweite zeigt, ob die erwartete Wiederverwendung funktioniert oder ob jeder Auftrag erneut große Mengen erzeugt. Für die Befehlsparameter und den Umgang mit Xcode-Builds ist die Apple-Dokumentation zu Command-Line-Tools die maßgebliche Referenz; lokale Hilfe und tatsächliche Runner-Parameter haben Vorrang vor Community-Skripten.

Eine belastbare Aufbewahrungsregel benennt Besitzer und Zeitpunkt: Arbeitsdaten nach Jobende, Caches nach einem definierten Alter oder Grenzwert, Archive erst nach abgeschlossener Auslieferung und Simulator-Testdaten nach Ende der jeweiligen Testmatrix. Ohne diese Zuordnung bleibt „Cache“ ein Sammelbegriff, unter dem versehentlich lieferrelevante Dateien verschwinden können.

04

Testverantwortung: iOS Simulator und Plattformkomponenten

Ein übergroßer iOS Simulator kann aus mindestens drei verschiedenen Beständen bestehen: installierte Runtime, angelegte Geräteinstanzen und von Tests erzeugte Daten. Diese Gruppen müssen getrennt inventarisiert werden. Die installierte Runtime ist eine Plattformkomponente; ein Simulator-Gerät ist eine Instanz; Logs, App-Daten und Testresultate gehören zum jeweiligen Testlauf.

xcrun simctl list runtimes
xcrun simctl list devices
xcrun simctl list --json > <BEWEISPFAD>/simctl-list.json
du -sh <SIMULATOR_BASISPFAD> 2>/dev/null

Vor jeder Entfernung wird dokumentiert, welche Runtime der aktuelle Testauftrag benötigt. Nicht verwendete Geräteinstanzen können nach Prüfung entfernt werden, wenn kein Debugging, keine laufende Testausführung und keine spätere Beweissicherung davon abhängt. Eine Runtime darf dagegen nicht entfernt werden, nur weil ihr Name alt wirkt. Die unterstützte Verwaltung zusätzlicher Komponenten ist über Apples Dokumentation zum Herunterladen und Installieren von Xcode-Komponenten zu prüfen.

Die Verwaltung der Geräte erfolgt über die unterstützten Xcode- und simctl-Funktionen. Apple erläutert die Geräteverwaltung im Device Hub sowie das Ausführen von Apps auf simulierten oder physischen Geräten. Geschützte Systempfade werden nicht direkt umgebaut, und ein aus dem Internet kopiertes Löschskript gilt nicht als Freigabe.

Die Abnahme besteht aus vier konkreten Prüfungen:

  1. Die benötigte Runtime erscheint in der lokalen Liste.
  2. Ein vorgesehenes Simulator-Gerät lässt sich starten.
  3. Der Testauftrag läuft mit dem vorgesehenen Ziel durch.
  4. Ein absichtlich unterbrochener oder getrennter Lauf kann gemäß Runner-Verfahren wieder aufgenommen werden.

Wenn nur Speicher freigegeben wurde, aber das Testziel nicht mehr startet, ist die Maßnahme zurückzurollen oder der Testverantwortliche zu informieren. Eine leere Simulator-Umgebung ist keine funktionierende Testumgebung.

05

Release-Verantwortung: Archive, Exporte und Signaturmaterial

Nach einem fehlgeschlagenen Archive-Schritt lautet die richtige Entscheidung nicht automatisch „Knoten löschen“. Zuerst wird festgestellt, ob ein vollständiges .xcarchive, ein Exportpaket, Symbol- oder Diagnosematerial bereits erzeugt wurde und ob ein Upload oder eine manuelle Prüfung noch aussteht.

find <ARCHIV_ROOT> -type d -name '*.xcarchive' -print 2>/dev/null
find <EXPORT_ROOT> -type f \( -name '*.ipa' -o -name '*.pkg' -o -name '*.dSYM.zip' \) -print 2>/dev/null
du -sh <ARCHIV_ROOT> <EXPORT_ROOT> 2>/dev/null

Ein Archive ist nicht dasselbe wie DerivedData. Es kann als Liefernachweis, Grundlage für Symbolication oder Ausgangspunkt eines erneuten Exports benötigt werden. Deshalb gelten dafür eigene Aufbewahrungsregeln. Apple beschreibt den Ablauf in der Dokumentation zur Archivierung und Verteilung von Apps und erläutert die Einbindung von Debugging-Informationen in dieser Referenz zu Archiven und Symbolen.

Signaturmaterialien werden nicht als Platzreserve behandelt. Schlüsselbund, Zertifikate, Provisioning-Profile und geheim zu behandelnde Konfigurationsdateien bleiben erhalten, sofern nicht ein gesondertes Sicherheits- oder Rotationsverfahren ihre Entfernung verlangt. Sie werden weder zusammen mit temporären Build-Dateien gelöscht noch in ein ungeschütztes Austauschverzeichnis verschoben.

Nach einer Bereinigung wird der Releasepfad vollständig geprüft: Archive erzeugen, Export ausführen, erwartete Dateien kontrollieren und den vorgesehenen Upload- oder Übergabeprozess testen. Erst wenn diese Schritte mit dem richtigen Signaturkontext funktionieren, darf der Knoten wieder als Release-Runner markiert werden.

06

Plattformbetrieb: Aufbewahrung, Isolation und Kapazitätsentscheidung

Der Plattformverantwortliche führt die Einzeldiagnosen in eine dauerhafte Regelung über. Für jeden Datenbestand müssen Besitzer, Entstehungsereignis, Aufbewahrungsgrund, Löschzeitpunkt und Wiederherstellungsweg dokumentiert sein. Das verhindert, dass ein manueller Eingriff auf einem gemeinsam genutzten Remote-Mac zur Standardlösung für jede spätere Störung wird.

Die Überwachung sollte nicht nur den freien Speicher anzeigen. Sinnvoll sind getrennte Warnungen für Dateisystem, Inodes, Arbeitsbereiche, DerivedData, Simulator-Bestände, Archive und Paketmanager-Caches. Der Alarm muss außerdem den ausführenden Benutzer und den Job nennen, weil ein einzelner Auftrag einen sonst unauffälligen Knoten innerhalb kurzer Zeit füllen kann.

Für einen gemeinsam genutzten Mac Runner gelten folgende Kontrollpunkte:

  • [ ] Neue Jobs werden bei kritischem Speicherstand nicht mehr angenommen.
  • [ ] Der betroffene Job, Commit, Benutzer und aktive Xcode-Pfad sind protokolliert.
  • [ ] Arbeitsbereiche, DerivedData, Simulator und Archive werden getrennt gemessen.
  • [ ] Eine Bereinigung läuft nur, wenn kein Prozess den betroffenen Pfad verwendet.
  • [ ] Die Löschliste enthält ausschließlich reproduzierbare und freigegebene Daten.
  • [ ] Der erste saubere Build wurde mit denselben Parametern wiederholt.
  • [ ] Ein zweiter Build bestätigt die erwartete Cache-Wiederverwendung.
  • [ ] Das benötigte Simulator-Ziel startet und führt den Test aus.
  • [ ] Archive, Export und Signaturpfad sind nach der Bereinigung geprüft.
  • [ ] Bei erneutem Wachstum ist ein Eigentümer für die nächste Maßnahme benannt.

Die Kapazitätsentscheidung fällt anhand des normalen Arbeitsprofils, nicht anhand eines einmalig freigeräumten Zustands. Wenn normale Build-, Test- und Archivdaten innerhalb der vereinbarten Aufbewahrung bereits den verfügbaren Speicher überschreiten, sollte die Plattform entweder Aufgaben trennen, die Aufbewahrung verkürzen oder einen Remote-Mac mit passenderer Speicherausstattung einsetzen. Ein einzelner Knoten für Entwicklung, Simulator-Matrix und Release kann zwar bequem sein, koppelt aber drei sehr unterschiedliche Speicherprofile.

Eine Trennung ist besonders sinnvoll, wenn Tests große Simulatorbestände erzeugen, während parallel Archive als Nachweise aufbewahrt werden müssen. Ein Entwicklungs- oder Testknoten kann dann reproduzierbare Daten nach Jobende anders behandeln als ein Releaseknoten. Die Entscheidung muss jedoch mit einem echten Projekt, realen Zielgeräten und dem tatsächlichen Signaturprozess geprüft werden; nominelle Hardwareangaben allein sagen nichts über die Wiederherstellung eines CI-Laufs aus.

Für Teams, die statt eines gemieteten Knotens einen eigenen Mac mini als Runner betreiben möchten, ist eine Übersicht zur Mac-mini-Beschaffung nur der Ausgangspunkt der Entscheidung. Vor einer Anschaffung sollten dieselben Speicherklassen, Aufbewahrungsfristen, Zugriffsrechte und Wiederherstellungstests dokumentiert werden. Ein eigener Rechner löst keine unkontrollierte Cache- oder Archivablage.

07

Remote-Mac-CI: Wiederherstellung oder Ressourcenwechsel

Das Problem Xcode No space left on device ist nach der ersten erfolgreichen Bereinigung erst dann gelöst, wenn die Ursache einer Datenklasse zugeordnet und die Wiederholung verhindert wurde. Ein einzelner erfolgreicher Build genügt nicht, wenn der zweite Lauf den Knoten erneut füllt oder der Simulator-Test ein anderes Ziel benötigt.

NodeMini ist für diesen Vergleich dann sinnvoll, wenn ein Entwicklerteam einen echten Remote-Mac mit SSH-, VNC- oder Webzugriff anhand des eigenen Xcode-Projekts prüfen möchte, ohne sofort dauerhaft Hardware zu beschaffen. Die verfügbaren Mac-Mietoptionen von NodeMini sollten dabei nicht nur nach dem nominellen Paket, sondern nach Speicherbedarf, Zugriff, Aufbewahrung und Wiederherstellung des konkreten CI-Ablaufs bewertet werden.

Die bisherige Lösung hat oft drei reale Nachteile: Ein gemeinsam genutzter Runner vermischt Testdaten und Release-Archive, manuelle Vollbereinigungen zerstören wichtige Beweise, und eine zu knapp bemessene lokale Mac-Ressource lässt sich während einer laufenden Lieferphase nicht flexibel anpassen. Ein Wechsel auf eine passende Remote-Mac-Umgebung kann diese Betriebsrisiken reduzieren, sofern vorab mit dem echten Projekt geprüft wird, welche Archive, Simulator-Runtimes, Caches und Signaturpfade erhalten bleiben müssen.

Für eine kurzfristige Störung, einen Migrationsversuch oder einen zusätzlichen CI-Knoten ist Mieten daher häufig der kontrollierbarere Weg als ein sofortiger Hardwarekauf. Für dauerhaft hohe Last, besondere physische Schnittstellen oder eine langfristig unveränderte Auslastung kann ein eigener Mac wirtschaftlicher sein. Entscheidend ist die dokumentierte Abnahme: derselbe Commit, dieselbe Xcode-Konfiguration, derselbe Simulator-Test und ein vollständiger Archive- und Exportlauf müssen auf dem ausgewählten NodeMini-Knoten erfolgreich nachvollziehbar sein.