← Zum Tagebuch

Wann Mac M4 CI aufteilen? Entscheidungsmodell & Migration auf Dual-Node (2026)

OpenClaw · 2026.06.23 · ~11 Min.

Mac M4 CI Build-Node und OpenClaw Gateway Dual-Node-Architektur

Anfang Juni packten wir Xcode CI und OpenClaw Gateway auf dieselbe kanadische M4-Maschine und hielten zwei Wochen durch — mit launchd Nice=-5 und begrenzter Build-Parallelität. Ab Woche drei meldeten Kollegen im IM: „Gateway hängt wieder.“ Die Build-Logs wirkten normal, doch der curl-Health-Check driftete in Spitzen von 50 ms auf über 400 ms. Wir senkten Parallelität, leerten DerivedData, buchten kurzzeitig 24 GB — das Problem ging von „zweimal täglich“ auf „einmal täglich“, blieb aber.

Das war kein Konfigurationsfehler, sondern das Same-Host-Ressourcenmodell am Limit. Ports kollidieren nicht (20300 vs. 18789), CPU-Kerne reichen — der Konflikt sitzt in Unified Memory und Swap. Dieser Artikel folgt auf Co-Location und launchd-Tuning: wann Dual-Node Pflicht wird, wie die Topologie aussieht und wie Sie Traffic umschalten, ohne Channels zu zerlegen. Offizielle Hinweise zu Speicher und Build-Verhalten: Apple-Dokumentation zu Xcode-Build-Cache; Tailscale-Setup: Tailscale-Installationsanleitung.

Kurz gesagt: Die Wasserscheide ist Ressourcenisolierung, nicht „noch eine Maschine kaufen“.

  • Vier harte Signale — eines reicht zum Split

    ≥50 Builds/Tag, ≥3 parallele Pipelines, Gateway für Endnutzer oder ≥3× Critical-Swap pro Woche — weiteres Nice-Tuning verschiebt nur den Termin.

    ≥50/Tag

  • Minimales Dual-Node: Build-Host + Gateway-Dedicated

    Build-Knoten 24 GB+ und große SSD; Gateway-Knoten 16 GB reichen für ~500 MB Dauerlast. Zwei M4 über Tailscale; öffentlich nur nötige Eingänge.

    16 GB Gateway

  • Migration = Zustand + DNS, nicht Neuinstallation

    rsync der Config, Token wiederverwenden, Tailscale MagicDNS umschalten; Build-Host läuft weiter, Gateway Blue/Green ≤15 Minuten.

    Blue/Green ≤15 min

1. Warum Same-Host plötzlich nicht mehr reicht

Viele Teams starten mit einem Cloud-Mac für drei Rollen: xcodebuild, OpenClaw Gateway auf 18789, gelegentlich VNC für Keychain. Bei wenig Last wirken 16 GB großzügig. Mit mehr Branches, parallelen UI-Tests und Channels von internem Pilot zu Produktions-IM wird die Speicherkurve von „Sägezahn“ zu „Plateau“ — zehn Minuten nach Build-Ende bleiben komprimierte Seiten über 8 GB, Gateway-Heap rutscht weiter in Swap.

Same-Host-Tuning (weniger Parallelität, höheres Nice, Cache leeren) senkt die Wahrscheinlichkeit überlappender Peaks, eliminiert Peaks nicht. Wenn APAC-Tagesbuilds und nordamerikanische Abend-IM-Spitzen fast sicher kollidieren, optimieren Sie nicht mehr Parameter — Sie wetten auf den Scheduler. Apple Silicon hat keinen separaten VRAM-Puffer; Xcode und Node.js-Gateway teilen denselben physischen Pool. Ab memory_pressure Warn spüren Nutzer Latenz-Jitter; CI sieht sporadische Timeouts und Signatur-Fehler.

Split bedeutet nicht „Mythos Skalierung“, sondern nicht komprimierbare Peaks trennen: Build-Spitzen nur auf dem Build-Knoten, Gateway-RAM nie von xcsbuildd verdrängt. Das entspricht der Logik in GitHub Actions Self-hosted macOS Runner auf Cloud Mac — dedizierter Runner ohne Desktop-Mix — hier getrennt werden Gateway und CI.

Für DACH-Teams mit dokumentierten SLAs ist der Moment oft nicht der erste Swap, sondern der dritte IM-Vorfall in einer Woche, bei dem Logs „grün“ sind, Nutzer aber „Gateway hängt“ melden. Dann ist Same-Host keine Kosteneinsparung mehr, sondern versteckte Ausfallzeit.

Ein hilfreiches Gedankenexperiment: messen Sie Gateway-P95 nur während aktiver xcodebuild-Jobs. Steigt die Latenz um Faktor 3–8, obwohl CPU-Auslastung unter 70 % bleibt, haben Sie kein Netzwerkproblem — Sie haben Speicher-Konkurrenz. In unserem Fall lag compressed memory nach dem Build noch zehn Minuten über 6 GB; der Node.js-Heap des Gateways konnte nicht stabil resident bleiben. Jeder Versuch, mit Nice oder weniger -jobs zu reagieren, senkte den Build-Durchsatz, ohne den Gateway-SLA zu retten. Das ist der klassische Same-Host-Falleffekt: zwei Teams optimieren gegeneinander auf derselben Maschine.

Wer bereits Self-hosted Runner auf Cloud Mac betreibt, kennt die Regel „kein Desktop, kein Gateway auf dem Runner“. Der Dual-Node-Split ist dieselbe Regel, nur dass Gateway hier kein Nebenprodukt, sondern produktionskritischer Dienst ist. Der Unterschied zu „einfach 32 GB buchen“: mehr RAM hebt die Decke für beide Peaks gleichzeitig, trennt sie aber nicht. Wenn der Build-Peak weiterhin 18–22 GB braucht, bleibt für Gateway nur der Rest — und bei parallelen UI-Tests ist der Rest zu klein.

2. Drei Topologien: Same-Host, Dual-Node, Triple-Node

Erst klassifizieren, dann kaufen:

  • T0 Same-Host: Ein M4 für Xcode Server / Self-hosted Runner + Gateway. Für <30 Builds/Tag, internes Gateway, tolerierbare Latenz-Spitzen.
  • T1 Dual-Node (Fokus): Knoten A nur CI (24 GB+, große SSD); Knoten B nur Gateway (16 GB). Tailscale oder Rechenzentrum-LAN; Channels/Dashboard → B, Build-Trigger → A.
  • T2 Triple-Node: Zusätzlich Signatur/Upload- oder paralleler Test-Host. Ab >150 Builds/Tag oder harter Trennung TestFlight/Compile; für die meisten Teams reicht T1.

Asymmetrische These: Nicht M4-Leistung fehlt, sondern zwei SLA-Klassen teilen sich einen Speicherpool. Gateway braucht 99,9 % stabile Antwort; CI braucht Durchsatz. Same-Host kompromittiert beide mit einem SLA.

T1 Dual-Node: Build-Host + Gateway-Dedicated Knoten A · CI Build M4 24GB+ · 1TB SSD xcodebuild / Runner DerivedData lokal :20300 Xcode Server Knoten B · Gateway-Dedicated M4 16GB · 256GB OpenClaw Gateway Channels / Dashboard :18789 stabile Latenz Tailscale <5ms Engineer SSH / CI-Trigger → A; IM / Mobile / Agent → B
Minimales Dual-Node-Modell: Build-Peaks und Gateway-SLA physisch getrennt

3. Same-Host vs. Dual-Node vs. Upgrade: Vergleich

Mac M4 CI Skalierungspfade (2026)
Dimension Weiter tunen Nice / weniger Parallelität Einzelhost 32 GB Mehr RAM, gleiche Topologie Dual-Node-Split CI + Gateway getrennt
WurzelursachePeak-Überlappung mildernRAM-Decke hebenZwei SLAs isolieren
Gateway-LatenzSchwankt mit BuildsBesser, nicht wegBuild-Zeit <100 ms möglich
Monatskosten (grob)NiedrigstMittel (Upgrade)Mittel (+16 GB Kleinhost)
Ops-AufwandNiedrigNiedrigMittel (+1 Host, Tailscale)
Passende Phase<30 Builds/Tag2 parallele Jobs, internes GW≥50/Tag oder externes GW
Split-Trigger-Checkliste (ein Treffer → T1)
Signal Schwelle Beobachtung Falsch positiv
Build-Frequenz≥50/TagCI-Logs / Runner-ZählerManuelles lokales Archive ausschließen
Parallelität≥3 volle Buildsxcodebuild -jobs, Queue-TiefeLeichtes Lint zählt nicht
Gateway-PublikumEndnutzer / 7×24 ChannelsProdukt-SLAReiner interner Webhook kann warten
Speicherdruck≥3× Critical/Wochememory_pressure-LogsEinmal-Leak zuerst fixen
Disk-Konkurrenz>50 GB/Monat + hoher I/O waitdf -h + iostatArchive aufräumen, dann bewerten
Upgrade ersetzt keinen Split
32 GB Same-Host passt zu „2 parallele Jobs + internes Gateway“. Ist Gateway extern live, verschiebt mehr RAM Jitter von dreimal auf einmal täglich — Nutzer spüren weiter „hängt wieder“.

4. Szenarien: Entscheidungsmatrix

  • Zwei-Personen-Team, <20 Builds/Tag, Gateway nur intern: T0, launchd-Tuning reicht.
  • APAC-Builds, Gateway für IM-Nutzer: direkt T1. Follow-the-sun überlappt Peaks fast sicher.
  • GHA Cloud Runner live, Gateway neu: Runner auf A, Gateway auf B; 18789 nicht auf dem Runner-Host.
  • TestFlight-Upload vs. Compile um Disk: erst T1; bei Bedarf T2 Signatur-Host — nicht mit diesem Runbook verwechseln.
  • Budget nur für einen Host: Gateway-SLA priorisieren, Builds nachts oder weniger parallel — Kompromiss, keine Dauerarchitektur.

Wenn Ihr Incident-Review zeigt, dass P95-Latenz nur während xcodebuild steigt, ist das kein Netzwerkproblem — es ist Speicher-Konkurrenz. T1 adressiert genau das, ohne die Build-Pipeline zu pausieren.

Für verteilte Teams mit Follow-the-sun gilt: selbst wenn Sie nachts in Nordamerika batchweise archivieren, bleibt der Gateway tagsüber für Agent-Sessions und IM-Channels aktiv. Die Wahrscheinlichkeit, dass ein Release-Build mit einem Produktions-Incident überlappt, steigt mit jedem neuen Feature-Branch. T0 funktioniert, solange Gateway „best effort“ ist; sobald Product einen Response-Time-SLA in Confluence verlinkt, sind Sie faktisch in T1-Pflicht — nur ohne zweite Maschine.

Budget-Einwand „nur eine Maschine“: priorisieren Sie Gateway-SLA und verschieben Sie Builds in Nachtfenster. Das ist ein Übergang, kein Zielbild. Innerhalb von 4–8 Wochen sehen wir typischerweise wieder dieselben Tickets, weil Commit-Frequenz steigt. Planen Sie von Anfang an den zweiten Knoten als 16 GB-Gateway-Host ein; der ROI kommt aus weniger Support-Zeit, nicht aus der absoluten Monatsmiete.

5. Empfohlene Stacks (kombinierbar)

  1. Minimales Dual-Node: Hashvps Kanada M4 24 GB (A, CI) + M4 16 GB (B, Gateway) + Tailscale tailnet + wöchentlich openclaw doctor. Standard-Upgrade von T0.
  2. CI-Hybrid: A mit Self-hosted Runner für GitHub Actions; B mit Gateway + Channels. Orchestrierung in GitHub, Ausführung auf macOS, Gateway ohne Build-Peaks. Entspricht „Umgebungssouveränität“ in macOS-Build-Markt 2027.
  3. Observability: Auf B Gateway-Latenz-Probe (curl alle 5 s) + auf A nach Build-Ende memory_pressure-Snapshot; zwei Wochen Daten reichen für Split-ROI gegenüber Management.

6. Typische Fehler vor der Migration

  • Erst CI stoppen, dann Gateway ziehen: CI-Stopp ist teuer; Gateway Blue/Green, CI läuft.
  • Neuinstallation statt rsync: Verlust von ~/.openclaw, Token, Channel-Pairing → alle müssen neu anmelden.
  • Zwei öffentliche IPs mit 18789: Während Cutover Tailscale oder internes DNS — nie zwei Gateways parallel an Channels.
  • Gateway auf Build-Host zu früh löschen: Rollback-Fenster: alter Prozess bleibt, nur DNS ändert sich.
  • Uhrzeit und Zertifikate: NTP-Drift >30 s → sporadische Token-Fehler; Migrationstag sudo sntp -sS time.apple.com.

7. Runbook: Dual-Node in sieben Schritten

Annahme: bisher mac-ci-01 mit CI+Gateway; neu mac-gw-02 (16 GB) nur Gateway. Tailscale installiert (siehe OpenClaw Ops Runbook).

Schritt 1: Baseline (Tag vor Migration)

Gateway P50/P95, Build-Anzahl, memory_pressure erfassen. openclaw status und Channel-Liste sichern.

bash — Baseline: Gateway-Latenz und Speicherdruck
# 延迟采样 60 次
for i in $(seq 1 60); do
  curl -o /dev/null -s -w "%{time_total}\n" http://127.0.0.1:18789/health
  sleep 5
done | sort -n | awk '{a[NR]=$1} END{print "p50="a[int(NR*0.5)],"p95="a[int(NR*0.95)]}'

memory_pressure
vm_stat | head -8

Schritt 2: Neuer Host + Tailscale

Auf mac-gw-02: macOS-Update, Homebrew, Node, Tailscale; Ping zu mac-ci-01 <5 ms. Kein xcodebuild auf B.

Schritt 3: rsync Gateway-Zustand (Wartungsfenster)

bash — OpenClaw-Config auf Gateway-Host syncen
# 在原机 mac-ci-01 执行;先停 Gateway 避免写入分裂
sudo launchctl unload /Library/LaunchDaemons/com.openclaw.gateway.plist

rsync -avz --delete \
  ~/.openclaw/ \
  builder@mac-gw-02.tailnet-abc.ts.net:~/.openclaw/

# 同步 launchd plist
scp /Library/LaunchDaemons/com.openclaw.gateway.plist \
  builder@mac-gw-02.tailnet-abc.ts.net:/tmp/

Schritt 4: Gateway auf neuem Host starten

bash — Service laden und Health prüfen
sudo cp /tmp/com.openclaw.gateway.plist /Library/LaunchDaemons/
sudo launchctl load /Library/LaunchDaemons/com.openclaw.gateway.plist

openclaw doctor
curl -s http://127.0.0.1:18789/health
sudo lsof -iTCP:18789 -sTCP:LISTEN

Schritt 5: Traffic — MagicDNS oder Reverse Proxy

Team-Gateway-Hostname (z. B. gateway.tailnet-abc.ts.net) auf neuen Host; Mobile/Channels auf neuen MagicDNS-Namen. Nicht Gateway auf Alt-Host während Cutover neu starten.

Schritt 6: Build-Host entlasten

Nach erfolgreichem Channel-Test auf B: Gateway launchd auf A entfernen, CI-Parallelität auf 5–6 (24 GB).

bash — Gateway von Build-Host entfernen
# mac-ci-01:确认已无流量打到 18789 后
sudo launchctl unload /Library/LaunchDaemons/com.openclaw.gateway.plist
sudo mv /Library/LaunchDaemons/com.openclaw.gateway.plist \
        /Library/LaunchDaemons/com.openclaw.gateway.plist.bak

defaults write com.apple.dt.Xcode \
  IDEBuildOperationMaxNumberOfConcurrentCompileTasks 6

Schritt 7: 48 Stunden beobachten + Rollback

.openclaw-Backup und plist.bak sieben Tage behalten. Bei P95 >200 ms oder Channel-Ausfall: DNS zurück, altes plist laden — CI-Queue unberührt. Details: OpenClaw Remote-Mac-Onboarding.

Während der Beobachtungsphase laufen Builds bewusst weiter: Sie wollen sehen, ob der Build-Knoten unter höherer Parallelität stabil bleibt, während Gateway-P95 auf B flach bleibt. Vergleichen Sie die Baseline aus Schritt 1 mit den gleichen Stundenfenstern nach der Migration. Typischer Erfolg: Critical memory_pressure auf A kann weiter vorkommen, aber nur noch während Builds — nie mehr korreliert mit Gateway-Latenz auf demselben Host, weil es keinen gemeinsamen Host mehr gibt.

8. FAQ

F1. Nur 16 GB — logische Rollen ohne zweiten Host?

Ersetzt keinen physischen Split. Zeitverschiebung (nachts bauen, tags Gateway) hilft kurz; bei Follow-the-sun oder 7×24 Channels kollidieren Peaks wieder. Logische Trennung lohnt als Beweis für Beschaffung: Latenz nach Gateway-Move messen.

F2. Muss Dual-Node Tailscale nutzen?

Nein, aber stark empfohlen. Anbieter-LAN, WireGuard oder SSH-Tunnel gehen auch; Tailscale bringt MagicDNS, ACLs, wenig Ops. Zwei Hashvps M4 in Kanada: RTT oft <2 ms — reicht für Build-Webhooks von B nach A.

F3. Dual-Node vs. einzelner 32 GB-Host?

Preis ähnlich: oft 24 GB Build + 16 GB Kleinhost vs. 32 GB Solo. Entscheidend ist nachweisbarer Gateway-SLA; externe Teams rechnen mit Ausfallminuten, nicht nur Monatsmiete.

F4. GHA gehosteter Runner — trotzdem eigener Mac?

Umgebungssouveränität. Gehostetes macOS pro Minute für Spitzen; Self-hosted Cloud Mac ab festen >50 Builds/Tag mit Keychain/DerivedData-Kontrolle. Gateway bleibt unabhängig vom Runner-Modell.

F5. Schnellster Rollback?

DNS zurück + launchctl load auf Alt-Host. Am Rollback-Tag keine Massen-Builds; erst Health + eine Channel-Nachricht, dann CI freigeben. Doppelte Zustandskopien bis Metriken stabil.

F6. Welche Metriken beweisen den Split gegenüber dem Management?

Zwei Wochen reichen. Führen Sie parallel auf dem Alt-Setup Gateway-P95 und memory_pressure-Critical-Events; nach Migration dieselben Metriken auf getrennten Hosts. Wenn P95 während Build-Spitzen von 400 ms auf <100 ms fällt und Critical-Events auf dem Gateway-Host null bleiben, ist der Business-Case klarer als jede CPU-Upgrade-Rechnung. Dokumentieren Sie außerdem „vermiedene Build-Wartezeit“: höhere Concurrent-Compile-Tasks auf 24 GB ohne Gateway-Risiko.

9. Fazit

Mac M4 CI-Split ist kein Scheitern, sondern die nächste Stufe nach erfolgreichem Same-Host-Tuning: Build und Gateway sind beide nötig, aber nicht mehr im selben RAM. Vier harte Signale, T1 für SLA-Trennung, sieben Schritte Blue/Green — die Wasserscheide ist Isolierung, nicht Maschinenzahl.

Stecken Sie in „Gateway hängt, Build darf nicht stoppen“, ist ein 16 GB Gateway-Dedicated-Host der pragmatischere Fix als weiteres Nice-Tuning. Builds auf 24 GB Cloud, Agent und Nutzer auf stabilem 18789 — das ist 2026 die bezahlbare Quasi-Produktions-Topologie für kleine Teams.

Dual-Node-Split mit zwei Cloud Mac mini

Nach dem Split braucht der Build-Host 24 GB und große SSD für DerivedData; der Gateway-Host kommt mit 16 GB für 7×24 niedrige Latenz. Hashvps Kanada M4 Bare Metal, dedizierte IPv4, SSH/VNC sofort — zwei Hosts in einer Region, niedrige Tailscale-Latenz, idealer T1-Einstieg, oft besser als hartes 32 GB-Upgrade auf einem Host.

Planen Sie den Wechsel von Same-Host zu Dual-Node, ist Hashvps Cloud Mac mini M4 ein starker Start für den zweiten Knoten Tarife ansehen und CI mit Gateway sauber trennen.

Hashvps · Mac Cloud

Build und Gateway trennen — stabiler

24GB CI + 16GB Gateway-Host, Bare-Metal-macOS, dedizierte IP, Tailscale-ready.

Pläne ansehen
Angebot