Skip to main content
Selbstgehostete Umgebungen befinden sich in der öffentlichen Beta auf Team- und Enterprise-Plänen; ein Inhaber aktiviert sie, indem er Selbstgehostete Umgebungen zulassen auf der Cloud-Umgebungen Admin-Seite einschaltet. Diese Seite ist die Flag- und Metrik-Referenz; siehe den Schnellstart für die Einrichtung und In Produktion bereitstellen für die Fleet-Rezepte.
Diese Seite ist die Referenz für die zwei Prozesse, die Sie in einer selbstgehosteten Umgebung ausführen: der Runner, der Claude Code Cloud-Sitzungen auf Ihren Hosts ausführt, und der optionale Autoscaling-Orchestrator, der Runner startet, wenn Sitzungen in die Warteschlange eingereiht werden. Jeder hat seine eigene Flag-Tabelle. Beide laufen auf Linux- oder macOS-Hosts, wobei die Standardwerte wie /workspace und ~/.claude angenommen werden. Führen Sie claude self-hosted-runner --help aus, um die autoritative Liste in Ihrer installierten Version zu erhalten. Metrische Reihen und einige wenige API-Felder verwenden immer noch pool für das, was diese Seiten eine Umgebung nennen; beide Begriffe bezeichnen dasselbe. Die Umgebungs-ID ist das Feld pool_id mit der Form ccpool_...: Überall dort, wo diese Seiten einen pool-Bezeichner anzeigen, benennt er die Umgebung. CLI-Flags und Umgebungsvariablen schreiben es als environment, wie z. B. --environment-secret-file; die veralteten pool-Schreibweisen funktionieren immer noch, wie die Zeile --environment-secret-file beschreibt.

Runner-CLI-Flags

Die meisten Flags haben eine entsprechende Umgebungsvariable. Wenn beide gesetzt sind, hat das Flag Vorrang. Duration-Flags nehmen Minuten oder Sekunden in der CLI, aber die gepaarte Umgebungsvariable ist immer in Millisekunden, angezeigt durch das Suffix _MS, und die Spalte Standard zeigt die Einheit des Flags: --exit-if-unused-min 10 entspricht SELF_HOSTED_RUNNER_IDLE_SHUTDOWN_MS=600000, und ein Helm-Wert wie SELF_HOSTED_RUNNER_STARTUP_TIMEOUT_MS: "15" bedeutet 15 Millisekunden, nicht die 15-Minuten-Standard. Die meisten Duration-Flags haben ein Maximum, das gewählt wurde, um jeden Timeout unter der 32-Bit-Timer-Obergrenze der Laufzeit von ungefähr 24,85 Tagen zu halten. Die --*-min Flags sind auf 10080 Minuten, 7 Tage begrenzt; --drain-grace-sec auf 604800 Sekunden, auch 7 Tage; und --drain-wait-sec auf 86400 Sekunden, 24 Stunden. --session-stop-grace-sec und --post-session-hook-timeout-sec sind unbegrenzt. Das Überschreiten einer Obergrenze verhält sich je nach Oberfläche unterschiedlich:
  • Flag: Der Start schlägt mit einem Fehler fehl.
  • Umgebungsvariable: Der Runner begrenzt den Wert auf die Timer-Obergrenze, anstatt ihn abzulehnen.

Timeout beim Sitzungsstart

Wenn eine Sitzung ihren Slot während eines Turns wie /code-review verloren hat, aktualisieren Sie den Runner und die Binärdatei des Kindprozesses auf v2.1.309 oder später. Von v2.1.299 bis v2.1.308 gab der Runner eine Sitzung, selbst mitten in einem Turn, frei, sobald der Start-Timeout ohne eine user- oder assistant-Nachricht abgelaufen war. Mit --startup-timeout-min <n> gibt der Runner den Slot einer Sitzung frei, wenn sich ihr Kindprozess nicht innerhalb von <n> Minuten nach dem Klonen initialisiert hat. Während eines Turns, der beginnt, bevor sich der Kindprozess initialisiert, behält die Sitzung ihren Slot, bis <n> Minuten ohne eine Zeile auf dem Activity-Kanal des Kindprozesses vergehen. Sobald sich der Kindprozess initialisiert, setzt der Runner diese Zählung zurück, und --release-idle-session-min steuert die Freigabe. Um eine Sitzung zu begrenzen, deren Kindprozess läuft, aber feststeckt, setzen Sie --kill-session-after-min.

Regellisten des Auto-Modus

Mit --server-auto-mode-lists legen Sie fest, welche Klassifikatorregeln des Auto-Modus von außerhalb des Runners die Sitzungen auf Ihren Runnern erreichen. Die Control Plane von Anthropic kann Regellisten mit einer Sitzung senden und den Runner auffordern, sie anzuwenden. Einige Einträge können Regeln sein, die ein Admin Ihrer Organisation geschrieben hat. Die Listen sind environment, soft_deny und allow:
  • environment: Ein Eintrag kann den Klassifikator dazu bringen, sowohl mehr als auch weniger zuzulassen.
  • soft_deny: Ein Eintrag blockiert eine Aktion, es sei denn, der Benutzer hat ausdrücklich darum gebeten oder eine allow-Ausnahme greift.
  • allow: Die Ausnahmen zu soft_deny-Einträgen.
Der Wert des Flags bestimmt, welche Listen der Runner anwendet:
  • no-allow: Der Standard. Wendet environment und soft_deny an und hält allow zurück. Ein environment-Eintrag kann den Klassifikator weiterhin dazu bringen, mehr zuzulassen, sodass der Standard nicht jede Lockerung ausschließt.
  • all: Wendet alle drei Listen an.
  • none: Wendet keine davon an. Wählen Sie none, um jede Lockerung durch diese Listen auszuschließen. Dabei entfallen auch die Einschränkungen von soft_deny.
Keine Runner-Einstellung veranlasst die Control Plane, den Runner zur Anwendung der Listen aufzufordern. Wenn sie nicht dazu auffordert, erhalten Sitzungen keine Liste, unabhängig davon, was Sie setzen. Um zu sehen, was geschehen ist, starten Sie den Runner mit --log-level debug. Für jede Sitzung protokolliert der Runner dann eine Zeile, die the server asked this runner to apply enthält, oder eine, die the server did not ask this runner to apply the auto mode lists it sends enthält.

Orchestrator-CLI-Flags

Der Unterbefehl self-hosted-runner orchestrator, der On-Demand-Runner erzeugt, akzeptiert --api-url, --environment-secret-file, --hooks-dir, --health-port und --log-level mit denselben Standardwerten wie der Runner und, wo das Flag des Runners einen hat, dieselbe Umgebungsvariable, außer dass --hooks-dir erforderlich ist und einen spawn-runner Hook enthalten muss. Es nimmt auch seine eigenen Flags:

SCM-Connector-Flags

Der SCM-Connector ist nicht verfügbar, daher lassen Sie die Flags in diesem Abschnitt nicht gesetzt. Wenn Sie --scm-connector-host setzen, wird die Verbindung nicht geöffnet, und der Orchestrator versucht weiterhin, sie zu verbinden. Runner starten weiterhin als Sitzungen in der Warteschlange. Der Connector ist eine stehende WebSocket-Verbindung vom Orchestrator zur Anthropic-Kontrolleben. Er ist so konzipiert, dass gehostete Pre-Session-Flows, wie der Repository-Picker und der Branch- oder Ref-Resolver, einen GitHub Enterprise Server-Host erreichen können, der nur von innerhalb Ihres Netzwerks erreichbar ist. Siehe Netzwerkanforderungen auf der GitHub Enterprise Server-Seite für das, was diese Flows benötigen. Bei jedem Verbindungsversuch sendet der Orchestrator sein bestehendes Umgebungsgeheimnis, und er versucht automatisch erneut mit exponentiellem Backoff, begrenzt auf 30 Sekunden plus Jitter.

Nur-Umgebungsvariablen-Einstellungen

Diese Runner-Einstellungen werden nur aus der Umgebung gelesen und decken Verhalten ab, das die meisten Bereitstellungen bei der Standardeinstellung belassen:

Telemetrie

Session-Kinder senden operative Telemetrie an Anthropic, es sei denn, Sie schalten sie aus. Kein Code oder Repository-Inhalt wird gesendet. Setzen Sie Telemetrie-Variablen auf dem Runner-Prozess; der Runner bekräftigt sie erneut, nachdem er von der Kontrolleben bereitgestellte Umgebungsvariablen angewendet hat, sodass die Einstellung des Operators immer Vorrang hat. Ein Steuerelement ist spezifisch für selbstgehostete Umgebungen: CLAUDE_CODE_BYOC_ENABLE_DATADOG=1 meldet sich für Datadog-Operationsmetriken an, die in selbstgehosteten Umgebungen standardmäßig aus sind. Die allgemeinen Claude Code-Telemetrie-Steuerelemente, DISABLE_TELEMETRY, DO_NOT_TRACK, DISABLE_ERROR_REPORTING und CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC, gelten für Session-Kinder wie in der Umgebungsvariablen-Referenz dokumentiert. DISABLE_GROWTHBOOK ist verwandt, aber anders: Das Setzen von DISABLE_GROWTHBOOK=1 deaktiviert das Abrufen von Feature-Flags, und die Telemetrie bleibt an, es sei denn, DISABLE_TELEMETRY ist auch gesetzt. CLAUDE_CODE_ENABLE_TELEMETRY ist nicht verwandt: Es aktiviert OpenTelemetry-Export zu Ihrem eigenen Collector, wie in Überwachung beschrieben, und steuert nicht Anthropics Analytik.

Health-Endpunkt

Der Runner bedient GET /healthz auf dem konfigurierten Health-Port. Die Antwort ist 200 OK, wann immer der Prozess am Leben ist, unabhängig davon, in welchem Zustand sich die Abfrageschleife befindet, sodass ein HTTP-Probe auf diesem Endpunkt nur einen toten Prozess erkennt. Der JSON-Body beschreibt den aktuellen Zustand:
Verwenden Sie last_poll_age_ms als Lebendigkeitssignal in benutzerdefinierten Proben; ein Wert, der unbegrenzt wächst, zeigt an, dass die Abfrageschleife steckt. Sowohl last_poll_at als auch last_poll_age_ms sind null, bis die erste Abfrage abgeschlossen ist. Der eigene /healthz-Endpunkt des Orchestrators auf seinem Health-Port gibt immer 200 zurück. Der Body enthält ein Feld connected, das meldet, ob die letzte Abfrage erfolgreich war, sowie Zählungen der Spawn-Queue pro Status in queue_counts. Um zu sehen, warum connected den Wert false hat, lesen Sie das Feld last_error auf oberster Ebene, das bei jeder erfolgreichen Abfrage auf null zurückgesetzt wird. Machen Sie Bereitschaftsprüfungen und Warnungen von connected abhängig statt vom Statuscode. Wenn der SCM-Connector konfiguriert ist, trägt der Body des /healthz des Orchestrators auch scm_connector_connected und ein Objekt scm_connector mit connected, last_connected_at, last_error, reconnects und requests_forwarded. Beide Felder sind null, wenn --scm-connector-host nicht gesetzt ist.

Prometheus-Metriken

Jeder Runner stellt Prometheus-Metriken unter GET /metrics auf demselben Port wie /healthz bereit. Wichtige Serien: Der Orchestrator stellt seine eigenen Serien unter GET /metrics auf demselben Port wie sein /healthz bereit: Wählen Sie für das Autoscaling die Serie, die zu Ihrer Skalierungsart passt, und filtern Sie sie, bevor sie in den Scaler eingespeist wird:
  • Skalierung nach Warteschlangentiefe: Speisen Sie claude_code_self_hosted_orchestrator_pool_pending_sessions in Ihren HPA- oder KEDA-Scaler ein, nicht queue_pending_sessions.
  • Skalierung nach Kapazität: Skalieren Sie anhand des Verhältnisses von active_sessions zu capacity des Runners.
  • Filtern nach connected: Filtern Sie die Abfrage pro Instanz mit claude_code_self_hosted_orchestrator_connected == 1, damit der veraltete Wert eines getrennten Replikats nicht in den Scaler gelangt.
Bei einem vollständigen Poll-Ausfall, bei dem alle Replikate getrennt sind, liefert die gefilterte Abfrage keine Daten. HPA behält bei einer fehlenden Metrik die aktuelle Replikatanzahl bei, der Prometheus-Scaler von KEDA liest das leere Ergebnis bei seinem Standardwert ignoreNullValues: "true" jedoch als null und skaliert herunter; setzen Sie ignoreNullValues: "false" im ScaledObject, optional mit einer fallback-Untergrenze für Replikate. Der folgende PodMonitor für den Prometheus Operator deckt beide Prozesse ab. Er wählt Pods anhand des Labels app.kubernetes.io/part-of: claude-code-self-hosted-runner und des benannten Ports health aus, die das Kubernetes-Rezept festlegt; passen Sie die Namespaces an Ihr Deployment an:

Beispiel-Alarmregeln

Diese Beispiel-Alarmregeln sind ein Ausgangspunkt; passen Sie die Schwellenwerte an die Größe Ihrer Flotte an:

Bei verlorenen Runnern und wartenden Sitzungen alarmieren

Laden Sie bei einer festen Flotte ClaudeRunnersBelowFloor. Laden Sie bei On-Demand-Runnern stattdessen ClaudeOrchestratorSessionsWaiting und ClaudeOrchestratorQueueWaitHigh.

Alarmieren, wenn eine feste Flotte Runner verliert

ClaudeRunnersBelowFloor wird ausgelöst, wenn 10 Minuten lang weniger registrierte und gescrapte Runner als die Untergrenze übrig sind:
  • Untergrenze: Setzen Sie die 2 in expr auf etwa die Hälfte Ihrer Replikatanzahl, aufgerundet. Behalten Sie bei drei Replikaten 2 bei; der Alarm wird dann ausgelöst, wenn nur noch ein Runner oder keiner übrig ist.
  • Namespace: Ersetzen Sie claude-runners im Matcher und in labels, und kopieren Sie den Alarm für jeden weiteren Namespace. Wenn Ihre Ziele kein namespace-Label haben, entfernen Sie den Matcher und das Label, da der Alarm sonst 0 liest und ausgelöst wird.
  • ClaudeRunnerPollStale und ClaudeRunnerPollErrors: Lassen Sie diese aus den Beispiel-Alarmregeln geladen, da ClaudeRunnersBelowFloor einen Runner, der nicht pollen kann, weiterhin mitzählt

Alarmieren, wenn Sitzungen auf On-Demand-Runner warten

ClaudeOrchestratorSessionsWaiting wird ausgelöst, wenn die Anzahl der Sitzungen, die auf einen Runner warten, 10 Minuten lang über 0 bleibt. ClaudeOrchestratorQueueWaitHigh wird ausgelöst, wenn mehr als 1 % der Wartezeiten in der Warteschlange in den letzten 10 Minuten 160 Sekunden überschritten haben und dies 5 Minuten lang anhält:
  • Schwellenwert: Wenn ständig irgendeine Sitzung wartet, erhöhen Sie das > 0 in ClaudeOrchestratorSessionsWaiting über die Anzahl, die Sie üblicherweise sehen
  • ClaudeOrchestratorDisconnected: Lassen Sie diesen Alarm aus den Beispiel-Alarmregeln geladen, da ClaudeOrchestratorSessionsWaiting etwa 2 Minuten, nachdem der letzte Orchestrator im Namespace die Verbindung verloren hat, nicht mehr ausgelöst wird

Metriken der Sitzungs-Kindprozesse durchreichen

Jede Sitzung läuft in ihrem eigenen Kindprozess mit eigenen OpenTelemetry-Metriken; bei einem --capacity-Wert über eins schreibt der Runner um, wie diese Metriken der Kindprozesse bereitgestellt werden. Wenn Sie OTEL_METRICS_EXPORTER=prometheus auf dem Runner-Host und CLAUDE_CODE_ENABLE_TELEMETRY=1 in der Umgebung der Sitzung setzen, zum Beispiel über Ihr Wrapper-Skript oder die eigene Umgebung des Runners, die Sitzungen erben, werden die Counter- und Gauge-Instrumente jedes Kindprozesses zusätzlich auf dem eigenen /metrics-Endpunkt des Runners neben den Serien des Runners bereitgestellt. Der Runner schreibt den Exporter des Kindprozesses so um, dass er per OTLP an einen nur über Loopback erreichbaren Empfänger auf dem Health-Port sendet, versieht jede Serie mit den Labels session_id und client_platform und entfernt die Serien einer Sitzung, wenn diese Sitzung endet. Histogramme werden nicht durchgereicht, und eine Metrik des Kindprozesses, deren Name mit dem eigenen Präfix des Runners kollidieren würde, wird verworfen. Beim Standardwert --capacity 1 greift diese Umschreibung nicht: Der Kindprozess der Sitzung bindet wie gewohnt seinen eigenen Prometheus-Endpunkt an Port 9464.

Metriken einer Sitzung mit denen des Runners verknüpfen

Um zu sehen, was inaktive Sitzungen gekostet haben, verknüpfen Sie claude_code_self_hosted_runner_session_idle_seconds des Runners über ccr_session_id mit der Kostenmetrik von Claude Code. Die Metrik des Runners trägt dieses Label nicht; fügen Sie es daher wie in dieser Abfrage mit label_replace hinzu:
Die Abfrage liefert ein Ergebnis pro Sitzung, die seit über zehn Minuten inaktiv ist: die Kosten in US-Dollar, die ihr Claude Code-Prozess bisher gezählt hat. Um eine andere Claude Code-Metrik zu verknüpfen, ersetzen Sie claude_code_cost_usage_total in der Abfrage. Die Abfrage funktioniert bei jedem --capacity-Wert.
  • session_id: Auf Port 9464 enthält dieses Label bei Claude Code-Metriken die eigene session.id von Claude Code, die zu keiner Serie des Runners passt. Eine Verknüpfung darüber liefert nichts; verknüpfen Sie daher über ccr_session_id.
  • Claude Code-Metriken haben kein ccr_session_id: Prüfen Sie, dass OTEL_METRICS_INCLUDE_SESSION_ID nicht auf false gesetzt ist

Semantik der Zähler für den Sitzungslebenszyklus

Die Zähler sessions_started_total, sessions_completed_total, sessions_failed_total und sessions_interrupted_total klassifizieren jede Sitzung danach, wie sie beendet wurde. Jeder gestartete Kindprozess einer Sitzung erhöht sessions_started_total beim Start, und genau einer der anderen drei Zähler wird beim Beenden erhöht; sessions_started_total minus der Summe der anderen drei entspricht also der Anzahl der aktuell laufenden Kindprozesse von Sitzungen.
  • completed: Die Sitzung wurde sauber beendet. Dazu gehört, dass der Kindprozess sich selbst mit Code 0 beendet, dass die Sitzung archiviert oder gelöscht wird, während der Kindprozess noch verbunden war, und dass der Runner den Slot sauber zurückgibt: durch Freigabe der Sitzung beim Inaktivitäts-Timeout, zum Ausmusterungszeitpunkt oder beim Limit --kill-session-after-min; durch einen Start-Timeout; oder durch eine serverseitige Aufhebung der Zuweisung, die die Poll-Schleife bemerkt hat, bevor der Kindprozess beendet wurde. Erhöht sessions_completed_total.
  • failed: Der Kindprozess hat sich selbst mit einem Code ungleich null beendet, entweder durch einen Absturz oder einen Einrichtungsfehler nach dem Start. Erhöht sessions_failed_total.
  • interrupted: Der Runner hat den Kindprozess aus einem betrieblichen Grund beendet, der weder ein Erfolg der Sitzung noch ein Fehler des Runners ist, etwa ein Drain oder das Beenden einer Sitzung, die sich noch auf dem Runner befand, als das Kulanzfenster SELF_HOSTED_RUNNER_MAX_LIFETIME_GRACE_MS nach ihrem Limit --kill-session-after-min endete. Ein rollierender Kubernetes-Neustart, der SIGTERM sendet, ist ein Beispiel für einen Drain. Erhöht sessions_interrupted_total.
Vor v2.1.260 beendete der Runner jede Sitzung, die ihr Limit --kill-session-after-min erreichte, und zählte sie in sessions_interrupted_total. Die Variable CLAUDE_RUNNER_EXIT_REASON des post-session-Hooks klassifiziert saubere Übergaben anders. Der Hook meldet diese als interrupted, weil der Runner den Kindprozess gestoppt hat: eine Freigabe, einen Start-Timeout, eine serverseitige Aufhebung der Zuweisung sowie ein Archivieren oder Löschen, das der Poll zuerst bemerkt hat. Diese Zähler erfassen dieselben Ereignisse als completed, weil der Slot sauber zurückgegeben wurde. Wenn Sie Hook-Empfangsbestätigungen direkt mit sessions_completed_total abgleichen, zählen Sie zu wenige abgeschlossene Sitzungen. Verwenden Sie den Hook für Garantien pro Sitzung und die Zähler für aggregierte Raten. In einer One-Shot-Umgebung, also --capacity 1 mit dem Standardwert --drain-grace-sec 0, wird jeder Runner-Prozess kurz nach dem Ende seiner einen Sitzung beendet. sessions_completed_total, sessions_failed_total und sessions_interrupted_total werden erst am Sitzungsende erhöht, unmittelbar vor diesem Beenden; ein Prometheus-Scrape alle 15 bis 60 Sekunden erfasst die Erhöhung daher selten, bevor die Serie des Runners verschwindet. Diese drei Zähler für das Sitzungsende sind die Endzähler, auf die sich der Rest dieses Abschnitts bezieht. sessions_started_total wird beim Start erhöht und bleibt während der gesamten Lebensdauer der Sitzung sichtbar, sodass er zuverlässig erscheint; in einer One-Shot-Umgebung entspricht er jedoch eher „aktuell laufenden Sitzungen“ als einer kumulierten Zählung. Verwenden Sie für das jeweilige Ziel die Serien in dieser Tabelle statt der Endzähler: Die orchestrator_*-Zeilen gibt es nur in Umgebungen, in denen der On-Demand-Orchestrator läuft. Verwenden Sie bei einer festen Flotte, deren Runner ihre Sitzungen mit einem --drain-grace-sec-Wert über 0 überdauern, sum(rate(claude_code_self_hosted_runner_sessions_started_total[5m])) für den Durchsatz; bei einer One-Shot-Flotte hat diese Serie dasselbe Problem mit dem Scrape-Fenster wie die Endzähler, verlassen Sie sich daher stattdessen auf die Anzahl der wartenden Sitzungen. Prüfen Sie den Rückstau im Tab Activity der Umgebung auf der Admin-Seite Cloud environments: Die Runner exportieren keine Serie für die Warteschlangentiefe. Verwenden Sie für die Berichterstattung über Ergebnisse pro Sitzung stattdessen den post-session-Hook: Er wird bei jedem Sitzungsende ausgelöst, bei dem ein Kindprozess gestartet wurde, abgesehen von einem abrupten Beenden des Runners wie einer VM-Preemption, gemäß dem eigenen Vertrag des Hooks.

Nächste Schritte