SpyBara
Go Premium

self-hosted-environments-reference.md 2026-11-09 23:02 UTC to 2026-11-10 21:57 UTC

This page contains 1 addition and 1 deletion.

2026
Tue 3 23:58 Mon 9 23:02 Tue 10 21:57 Wed 11 22:59

Referenz für selbstgehostete Umgebungen

Vollständige Referenz für den selbstgehosteten Runner und Orchestrator: CLI-Flags, Umgebungsvariablen und Prometheus-Metriken.

[!NOTE]

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.

Flag Env var Standard Beschreibung
--api-url <url> keine https://api.anthropic.com API-Basis-URL. Nur zum Testen überschreiben.
--base-dir <path> SELF_HOSTED_RUNNER_BASE_DIR /workspace; keine unter Windows Verzeichnis für Repository-Checkouts und pro-Sitzungs-Arbeitsverzeichnisse. Der Runner benötigt Schreibzugriff auf diesen Pfad oder sein übergeordnetes Verzeichnis. Der Runner erstellt das Verzeichnis beim Start und beendet sich mit cannot create or write to base directory, wenn er es nicht erstellen oder beschreiben kann. Vor v2.1.225 erstellte der Runner das Verzeichnis, wenn die erste Sitzung startete, sodass ein unbrauchbarer Pfad Sitzungen fehlschlagen ließ, anstatt beim Start zu fehlschlagen. Unter Windows, das kein unterstützter Runner-Host ist, gibt es keinen Standard: Der Runner beendet sich beim Start, es sei denn, Sie übergeben das Flag oder setzen die Variable. Verwenden Sie denselben Wert auf jedem Runner in einer Umgebung. Siehe Halten Sie das Basisverzeichnis und die Kapazität auf allen Runnern identisch.
--capacity <n> keine 1 Maximale gleichzeitige Sitzungen, die dieser Runner verarbeitet. Alle Sitzungen gehören demselben gesperrten Owner. Verwenden Sie denselben Wert auf jedem Runner in einer Umgebung; siehe Halten Sie das Basisverzeichnis und die Kapazität auf allen Runnern identisch.
--client-label <label> SELF_HOSTED_RUNNER_CLIENT_LABEL der Hostname des Hosts Beschriften Sie den Runner, den er beim Registrieren sendet. Der Runner meldet ihn auch als das Label client_label von claude_code_self_hosted_runner_info. Erfordert Claude Code v2.1.248 oder später.
--configure-git SELF_HOSTED_RUNNER_CONFIGURE_GIT=1 aus Beim Start globale Git-Identität schreiben, Anthropic-Commit-Signing aktivieren, Git-Push-Verhandlung einschalten und Commit-Hooks installieren, die einen Co-authored-by: Trailer anhängen. Push-Verhandlung erfordert Claude Code v2.1.257 oder später. Siehe Git konfigurieren.
--confine-repo-settings <mode> SELF_HOSTED_RUNNER_CONFINE_REPO_SETTINGS warn Setzt den Modus des Schutzes, der eine Sitzung kennzeichnet, wenn die festgeschriebenen Einstellungen eines Repositorys versuchen, Schreib- oder Lesezugriff außerhalb des eigenen Arbeitsbereichs dieser Sitzung zu gewähren, Umgebungsvariablen zu setzen oder die Sandbox- oder Hooks-Haltung des Operators zu überschreiben, wie sandbox.enabled: false oder disableAllHooks. Der Standard warn protokolliert die Verletzung und startet die Sitzung trotzdem, enforce lehnt die Sitzung ab, und off deaktiviert den Scan. Siehe Härten Sie Ihre Bereitstellung.
--debug-token-dir <path> SELF_HOSTED_RUNNER_DEBUG_TOKEN_DIR nicht gesetzt Schreiben Sie Live-Tokens zur Überprüfung auf die Festplatte. Nur zum Debuggen; nicht in der Produktion verwenden.
--defer-shutdown-max-min <n> SELF_HOSTED_RUNNER_DEFER_SHUTDOWN_MAX_MS 0 Beim ersten SIGTERM oder SIGINT bedienen Sie weiterhin die bereits angehängten Sitzungen, anstatt sie zu entleeren, und geben dann alles frei, das noch angehängt ist, N Minuten später und beenden sich. Erhöhen Sie das Stop-Timeout Ihres Hosts, bevor Sie dies setzen. Siehe Verschieben Sie die Entleerung über das erste Signal hinaus. 0 deaktiviert. Erfordert Claude Code v2.1.238 oder später.
--drain-grace-sec <n> SELF_HOSTED_RUNNER_DRAIN_GRACE_MS 0 Bis der Runner ein Shutdown-Signal empfängt oder seine Ruhestandszeit erreicht, steuert, wann der Runner beendet wird, nachdem seine aktiven Sitzungen beendet sind: 0 beendet sich sofort ohne Abfrage nach mehr, und ein positiver Wert hält den Runner am Leben und fragt die Warteschlange des gesperrten Owners N Sekunden lang erneut ab, auf Kosten der Pro-Sitzungs-Container-Isolation, die im Härtungsabschnitt beschrieben ist. Nach einem ersten Signal, das Sie mit --defer-shutdown-max-min verschoben haben, beendet sich der Runner, sobald er keine Sitzungen mehr hält, unabhängig davon, was Sie hier setzen.
--drain-marker-file <path> SELF_HOSTED_RUNNER_DRAIN_MARKER_FILE nicht gesetzt Markierungsdatei, die Ihr Host schreibt, um eine ordnungsgemäße Entleerung anzukündigen, bevor SIGTERM gesendet wird. Wenn die Datei existiert, wenn die Entleerung beginnt, meldet der Runner seinen Ausstieg an Anthropic als Host-Entleerung statt als einfaches Shutdown-Signal. Die Entleerung selbst, einschließlich des --drain-wait-sec Wartens, läuft gleich wie ohne das Flag. Benennen Sie einen Pfad auf einem lokalen Dateisystem, auf den Sitzungen nicht schreiben können. Erfordert Claude Code v2.1.271 oder später.
--drain-wait-sec <n> SELF_HOSTED_RUNNER_DRAIN_WAIT_MS 0 Sobald die Entleerung beginnt, was bei SIGTERM der Fall ist, es sei denn, Sie setzen --defer-shutdown-max-min, warten Sie bis zu N Sekunden, damit der laufende Turn und die Hintergrundaufgaben jeder Sitzung beendet werden, bevor Sie das Kind beenden. Während dieses Wartens zählt der Runner eine Hintergrundaufgabe, die gerade beendet wurde, als immer noch laufend, bis der Folge-Turn, der ihr Ergebnis liest, beginnt, für höchstens das Fenster SELF_HOSTED_RUNNER_BG_RESULT_GRACE_MS. Erhöhen Sie auch Ihr Stop-Timeout.
--environment-secret-file <path> SELF_HOSTED_RUNNER_ENVIRONMENT_SECRET erforderlich Pfad zu einer Datei, die das Umgebungsgeheimnis enthält, oder für Runner, die vom Orchestrator erzeugt werden, das einmalige Work-Order-JWT. SELF_HOSTED_RUNNER_ENVIRONMENT_SECRET trägt den Geheimniswert direkt, nicht einen Dateipfad. Das ältere Flag --pool-secret-file und die Variable SELF_HOSTED_RUNNER_POOL_SECRET funktionieren immer noch und geben eine Veraltungswarnung auf stderr aus; Preview-Programm-Runner-Builds älter als 2.1.216 erkennen nur diese älteren Namen.
--exec-path <path> SELF_HOSTED_RUNNER_EXEC_PATH eigene Binärdatei Binärdatei oder Wrapper-Skript zum Erzeugen für jede Sitzung. Siehe Wrapper-Skripte.
--exit-if-unused-min <n> SELF_HOSTED_RUNNER_IDLE_SHUTDOWN_MS 0 Beenden Sie sich nach N Minuten Abfrage ohne jemals zugewiesene Arbeit, für Autoscaler-Skalierung nach unten. 0 deaktiviert.
--git-host-rewrite <from>=<to> keine nicht gesetzt Schreiben Sie https://<from>/... Quell-URLs zu https://<to>/... um, bevor Sie klonen, für Split-Horizon-DNS. Wiederholbar; nur Flag.
--git-ssh-rewrite <host> keine nicht gesetzt Schreiben Sie https://<host>/... Quell-URLs zu git@<host>:... um, bevor Sie klonen, für SSH-only Git-Hosts. Wiederholbar; nur Flag.
--health-port <port> SELF_HOSTED_RUNNER_HEALTH_PORT 8080 Port für den /healthz- und /metrics-Listener. Setzen Sie 0, um zu deaktivieren.
--hold-idle-file <path> SELF_HOSTED_RUNNER_HOLD_IDLE_FILE nicht gesetzt Datei, die Ihr Host fortlaufend ändert, um eine untätige Sitzung auf dem Runner zu halten. Siehe Eine untätige Sitzung behalten, während ihre Prozesse laufen. Erfordert Claude Code v2.1.311 oder später.
--hooks-dir <path> SELF_HOSTED_RUNNER_HOOKS_DIR nicht gesetzt Verzeichnis von Lifecycle-Hook-Skripten. Siehe Lifecycle-Hooks.
--host-config-snapshot <mode> SELF_HOSTED_RUNNER_HOST_CONFIG_SNAPSHOT disk Wo der Runner den Startup-Snapshot des Host-Konfigurationsverzeichnisses aufbewahrt, das er jede Sitzung von dort aus startet. disk kopiert den Snapshot in ein vom Runner verwaltetes Verzeichnis unter --base-dir und überprüft bei jedem Sitzungsstart jede Datei gegen einen In-Memory-Digest. Wenn eine Datei in der Kopie geändert wurde, schlägt die Sitzung fehl und der Runner lehnt Sitzungen ab, bis Sie ihn neu starten. memory hält den gesamten Snapshot auf dem Heap, begrenzt auf 64 MiB; über der Grenze starten Sitzungen ohne Host-Konfiguration und zeigen einen entsprechenden Hinweis. Wenn der Runner den Disk-Snapshot nicht schreiben kann, protokolliert er den Fehler und verwendet memory für diesen Durchlauf. Erfordert Claude Code v2.1.271 oder später.
--kill-session-after-min <n> SELF_HOSTED_RUNNER_MAX_LIFETIME_MS 0 Begrenzen Sie eine Sitzung auf N Minuten Wanduhr, als Sicherheitslimit für steckengebliebene Sitzungen. In v2.1.260 oder später gibt der Runner eine Sitzung frei, die das Limit erreicht, damit sie in der nächsten Nachricht des Benutzers fortgesetzt werden kann, und beendet sie nur, wenn sie sich noch auf dem Runner befindet, wenn das Gnadenfenster SELF_HOSTED_RUNNER_MAX_LIFETIME_GRACE_MS endet. Vor v2.1.260 beendete der Runner die Sitzung beim Limit. Siehe Einige Sitzungen zählen nicht als untätig für die Details und wie Sie einen Wert wählen. 0 deaktiviert.
--lock-to-account <id> SELF_HOSTED_RUNNER_LOCK_TO_ACCOUNT nicht gesetzt Sperren Sie den Runner beim Start vorab auf ein bestimmtes Konto, anstatt beim ersten Session zu sperren. Akzeptiert eine E-Mail-Adresse oder eine user_... ID in der Organisation der Umgebung. Ein vorgespannter Runner nimmt niemals Claude Tag-Kanal-Sitzungen auf, die kein Konto haben.
--log-file <path> SELF_HOSTED_RUNNER_LOG_FILE nicht gesetzt Spiegeln Sie Runner-Protokolle zusätzlich zu stdout und stderr in eine Datei, erstellt mit 0600-Berechtigungen. Erforderlich für self-hosted-runner doctor, um Protokolle lokal zu verfolgen.
--log-level <level> keine info info oder debug
--max-hold-min <n> SELF_HOSTED_RUNNER_MAX_HOLD_MS 1440 Geben Sie mit --hold-idle-file eine gehaltene Sitzung N Minuten, nachdem sie untätig wurde, trotzdem frei. Ein Wert kleiner oder gleich --release-idle-session-min hält nichts. 0 schaltet das Halten aus. Erfordert Claude Code v2.1.311 oder später.
--post-session-hook-timeout-sec <n> SELF_HOSTED_RUNNER_POST_SESSION_HOOK_TIMEOUT_MS 60 Budget für den post-session Hook am Ende jeder Sitzung, einschließlich Runner-Shutdown
--proxy-authorization-command <command> SELF_HOSTED_RUNNER_PROXY_AUTHORIZATION_COMMAND nicht gesetzt Shell-Befehl, den der Runner für jede Verbindung zu Ihrem Egress-Proxy ausführt, wobei seine gekürzte Standardausgabe als Wert des Headers Proxy-Authorization verwendet wird. Erfordert HTTPS_PROXY oder HTTP_PROXY, und kann nicht mit --proxy-authorization-file kombiniert werden. Siehe Authentifizieren Sie sich bei einem Egress-Proxy. Erfordert Claude Code v2.1.238 oder später.
--proxy-authorization-file <path> SELF_HOSTED_RUNNER_PROXY_AUTHORIZATION_FILE nicht gesetzt Datei, die der Runner für jede Verbindung zu Ihrem Egress-Proxy liest, wobei ihr gekürzter Inhalt als Wert des Headers Proxy-Authorization verwendet wird. Verwenden Sie dieses Flag für ein Token, das ein anderer Prozess an Ort und Stelle rotiert. Trägt dieselben Anforderungen wie --proxy-authorization-command und kann nicht damit kombiniert werden. Siehe Authentifizieren Sie sich bei einem Egress-Proxy. Erfordert Claude Code v2.1.238 oder später.
--push-outcome-on-release SELF_HOSTED_RUNNER_PUSH_OUTCOME_ON_RELEASE aus Bei einem vom Runner initiierten Sitzungsende, wie einer Entleerung oder Idle-Freigabe, pusht der Runner primäre Sitzungs-Branches mit neuen Commits zu origin, bevor er den Arbeitsbereich löscht. Best-Effort; fügt 30 Sekunden zum Shutdown-Budget hinzu. Erfordert Git 2.29 oder neuer, um von ihnen fortzufahren. Beschränken Sie den Push-Zugriff auf claude/* Refs; siehe Fortgesetzte Sitzungen verlieren nicht gepushte Arbeit. Die Repositorys eines checkout Hooks werden nicht gepusht; erstellen Sie Snapshots davon im post-session Hook.
--release-idle-session-min <n> SELF_HOSTED_RUNNER_SESSION_IDLE_MS 0 Geben Sie einen Sitzungs-Slot nach N Minuten Inaktivität frei, sobald ein Turn beendet ist oder die Sitzung auf die Aktion des Benutzers wartet. Einige Sitzungen zählen nicht als untätig, koppeln Sie daher mit --kill-session-after-min. Eine beendete Hintergrundaufgabe hält die Sitzung höchstens für das Fenster SELF_HOSTED_RUNNER_BG_RESULT_GRACE_MS beschäftigt. Um eine Freigabe zu verzögern, setzen Sie --hold-idle-file. 0 deaktiviert.
--remove-session-state [bool] SELF_HOSTED_RUNNER_REMOVE_SESSION_STATE aus Entfernen Sie die Pro-Sitzungs-Verzeichnisse einer Sitzung unter <base-dir>/_sessions/, wenn die Sitzung auf diesem Runner endet, unabhängig vom Ergebnis. Verwenden Sie einen vorgefüllten Checkout erneut beschreibt, was sie enthalten und wer sie lesen kann, wenn sie bleiben. Die Entfernung ist Best-Effort: Die Pro-Sitzungs-Verzeichnisse bleiben an Ort und Stelle, wenn der Runner beendet wird oder seine Drain-Frist erreicht, bevor die Bereinigung ausgeführt wird. Mit dem Flag an, wird das Debug-Protokoll einer fehlgeschlagenen oder unterbrochenen Sitzung nicht auf der Festplatte gespeichert. Erfordert Claude Code v2.1.268 oder später.
--retire-at <epoch-seconds> SELF_HOSTED_RUNNER_RETIRE_AT nicht gesetzt Ruhestand des Runners bei einem absoluten Unix-Zeitstempel in Sekunden, für Infrastruktur, die den Runner zu einem bekannten Zeitpunkt beendet; Runner-Lebenszyklus beschreibt die Freigabesequenz und wie Sie die Marge dimensionieren. Werte vor 2001 oder nach dem Jahr 5138 werden vom Flag abgelehnt und von der Umgebungsvariable ignoriert.
--server-auto-mode-lists <mode> SELF_HOSTED_RUNNER_SERVER_AUTO_MODE_LISTS no-allow Welche der Regellisten des Auto-Modus-Klassifikators, die die Control Plane mit einer Sitzung sendet, diese Sitzung erreichen dürfen: all, no-allow oder none. Unter Regellisten des Auto-Modus erfahren Sie, was jeder Wert anwendet. Ein ungültiger Wert stoppt den Runner beim Start. Erfordert Claude Code v2.1.295 oder später.
--session-stop-grace-sec <n> SELF_HOSTED_RUNNER_SESSION_STOP_GRACE_MS 5 Wie lange Sie warten, bis der Claude-Prozess nach einer Sitzung sauber beendet wird, bevor Sie ihn gewaltsam beenden. Erhöhen Sie den Wert, wenn die eigenen SessionEnd Hooks des Kindes mehr Zeit benötigen.
--startup-timeout-min <n> SELF_HOSTED_RUNNER_STARTUP_TIMEOUT_MS 15 Wie lange auf einen Kindprozess gewartet wird, der sich nicht initialisiert hat, bevor der Slot der Sitzung freigegeben wird. Unter Timeout beim Sitzungsstart erfahren Sie, wo die Zählung beginnt und welche Sitzungen er weiterlaufen lässt. 0 deaktiviert den Timeout.
--trust-workspace [bool] SELF_HOSTED_RUNNER_TRUST_WORKSPACE an Seed persistierte Vertrauenswürdigkeit für die Repository-Pfade jeder Sitzung, sodass im Repo festgeschriebene permissions.allow und additionalDirectories berücksichtigt werden. Setzen Sie false, um im Repo festgeschriebene Berechtigungszuschüsse zu verwerfen und Zulassungsregeln stattdessen in der Host-Konfiguration settings.json zu konfigurieren; Repository-festgeschriebene sandbox.* Einstellungen gelten trotzdem, weshalb der Repo-Settings-Schutz sie unabhängig von diesem Flag scannt.
--use-anthropic-git-proxy CLAUDE_RUNNER_USE_GIT_PROXY=1 aus Klonen Sie Repositorys auf github.com über den Anthropic Git-Proxy anstatt über kundenverwaltete Git-Authentifizierung. Erfordert --capacity 1 und Git 2.32 oder neuer; der Runner weigert sich, andernfalls zu starten. Erfordert außerdem Claude Code v2.1.267 oder später. Ersetzt die Rewrite-Flags.

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:

Flag Standard Beschreibung
--hook-concurrency <n> 4 Maximale spawn-runner Hooks, die parallel laufen. Begrenzt auch, wie viele Spawn-Anfragen pro Abfrage beansprucht werden. Der Orchestrator sucht erst dann nach neuen Spawn-Anfragen, wenn jeder von ihm gestartete Hook beendet ist, sodass ein langsamer Hook die nächsten Hooks dieses Orchestrators verzögert.
--hook-timeout <sec> 60 Beenden Sie den Prozessbaum des Hooks nach dieser vielen Sekunden. Das Timeout plus seine 5-Sekunden-Kill-Gnadenfrist müssen unter --expected-spawn-seconds bleiben; der Orchestrator erzwingt dies beim Start.
--expected-spawn-seconds <sec> 120 Erwartete p99-Zeit vom Empfang einer Spawn-Anfrage durch den Orchestrator bis zur Registrierung des Runners, einschließlich einer etwaigen Wartezeit auf Kapazität auf Ihrer Plattform. Der Server erzwingt einen Bereich von 10 bis 3600. Wird bei jeder Abfrage als Server-seitige Lease gesendet: Wenn sich kein Runner registriert, bevor sie verstreicht, wird die Sitzung mit einer frischen Bestellungs-ID erneut angeboten. Alle Replikas müssen diesen Wert teilen.
--min-idle <n> 0 Halten Sie mindestens N untätige Session-Slots frei, indem Sie proaktiv Standby-Runner erzeugen. 0 deaktiviert Vorwärmung. Koppeln Sie mit dem --exit-if-unused-min des Runners, sodass überschüssige Standby-Runner sich selbst zurückfordern.
--shutdown-drain-sec <n> 0 Bei SIGTERM werden keine Spawn-Anfragen mehr abgefragt, und laufende spawn-runner Hooks sowie eine etwaige unbeantwortete Abfrage erhalten bis zu diese Anzahl an Sekunden Zeit zum Abschließen, bevor alles Verbleibende gestoppt wird. Bei 0 wird sofort gestoppt. Maximum 3600, was der Orchestrator beim Start erzwingt. Hinweise zur Wahl eines Werts finden Sie unter --shutdown-drain-sec und den Stopp-Timeout des Orchestrators dimensionieren. Erfordert Claude Code v2.1.299 oder höher.
--debug-dir <path> nicht gesetzt Schreiben Sie die Work-Order und Hook-Stderr jeder Spawn-Anfrage auf die Festplatte. Nur zum Debuggen; niemals in der Produktion setzen.

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.

Flag Standard Beschreibung
--scm-connector-host <host[:port]> nicht gesetzt GitHub Enterprise Server-Hostname, an den Anfragen weitergeleitet werden. Der Port ist standardmäßig 443.
--scm-connector-id <n> erforderlich mit --scm-connector-host Die numerische ID der GitHub Enterprise Server-Verbindung Ihrer Organisation.
--scm-connector-provider <slug> ghe Pfadsegment, das den Anbieter identifiziert, passend zu ^[a-z0-9-]{1,32}$.
--scm-connector-ca-file <path> nicht gesetzt Zusätzliches CA-Bundle im PEM-Format für TLS-Verbindungen zum GitHub Enterprise Server-Host.
--scm-connector-host-rewrite <from>=<to_host:to_port> nicht gesetzt Nur für End-to-End-Tests: leitet die TCP-Verbindung um, während der Host-Header und TLS SNI als --scm-connector-host beibehalten werden.

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:

Env var Standard Beschreibung
SELF_HOSTED_RUNNER_BG_RESULT_GRACE_MS 30000 Wie lange der Runner eine Sitzung als beschäftigt betrachtet, nachdem eine Hintergrundaufgabe beendet ist, während der Folgezug, der das Ergebnis liest, nicht gestartet hat. Die Zeilen --drain-wait-sec und --release-idle-session-min beschreiben, wo die Sperre bei Entleerung und Idle-Freigabe angewendet wird, und Runner-Lebenszyklus beschreibt, wo sie bei --retire-at Ruhestand angewendet wird. 0 oder ein unbrauchbarer Wert fällt auf den Standard zurück, sodass die Sperre nicht ausgeschaltet werden kann. Erfordert Claude Code v2.1.228 oder später.
SELF_HOSTED_RUNNER_HOST_CONFIG_DIR ~/.claude Verzeichnis, das in den Startup-Snapshot des Runners erfasst und in die CLAUDE_CONFIG_DIR jeder Sitzung eingegeben wird; Änderungen auf der Festplatte gelten nach einem Runner-Neustart. Das Setzen der Variable verschiebt auch, wo der Runner .claude.json für MCP-Seeding liest, sodass das Setzen, einschließlich auf seinen eigenen Standard, diese Suche verlagert; zeigen Sie auf ein leeres Verzeichnis, um das Seeding vollständig zu deaktivieren.
SELF_HOSTED_RUNNER_MAX_LIFETIME_GRACE_MS 900000 Wie lange der Runner wartet, nachdem eine Sitzung ihr --kill-session-after-min Limit erreicht hat, damit ein laufender Zug beendet wird oder die Freigabe abgeschlossen wird, bevor die Sitzung beendet wird
SELF_HOSTED_RUNNER_POST_TURN_SETTLE_MS 7000 Obergrenze für die Zeit, die der Runner eine Sitzung als beschäftigt für die --drain-wait-sec Entleerung nach Abschluss eines Zugs zählt, während der Prozess der Sitzung das Ende des Zugs an Anthropic meldet. 0 oder ein unbrauchbarer Wert fällt auf den Standard zurück, sodass die Sperre nicht ausgeschaltet werden kann. Erfordert Claude Code v2.1.275 oder später.
SELF_HOSTED_RUNNER_SIGKILL_GRACE_MS 30000 Wie lange der Runner wartet, bis das Betriebssystem SIGKILL an ein Kind sendet, das in nicht unterbrechbarem I/O steckt, bevor es sich selbst beendet. Mindestens --post-session-hook-timeout-sec plus 15 Sekunden, und 30 weitere, wenn --push-outcome-on-release gesetzt ist, sodass das effektive Minimum 75 Sekunden bei Standardwerten ist.
CLAUDE_RUNNER_FETCH_DEPTH 50 Git-Fetch-Tiefe für frische Klone. Setzen Sie eine positive Ganzzahl oder full oder 0 für einen vollständigen Fetch. Informationen zu einem Klon, der sich bereits im Arbeitsbereich befindet, finden Sie unter Einen vorgewärmten Checkout wiederverwenden.
CLAUDE_RUNNER_FETCH_SERVER_PROGRESS_CAP_MS 600000 Wie lange in Millisekunden pro Versuch ein Git-Fetch auf seine ersten Daten warten darf, während die eigenen Fortschrittszahlen des Git-Servers weiter steigen, etwa wenn der Server das Pack für ein großes Repository vorbereitet. 0 oder off schaltet das Warten aus: Ein solcher Fetch wird dann nach zwei Minuten ohne Daten abgebrochen. Jede andere Ganzzahl wird auf einen Wert zwischen 120000 und 1800000 begrenzt, also 2 bis 30 Minuten. Erfordert Claude Code v2.1.295 oder später.
CLAUDE_RUNNER_SKIP_GIT_VERIFY nicht gesetzt Wenn 1, überspringen Sie die .git Präsenzprüfung, nachdem ein checkout Hook ausgeführt wird. Setzen Sie dies, wenn Ihr Hook eine Nicht-Git-Quelle materialisiert.
FORCE_AUTOUPDATE_PLUGINS nicht gesetzt Wenn 1, lassen Sie Plugin-Marktplätze automatisch aktualisieren, obwohl die Binärdatei angeheftet ist
CLAUDE_CODE_DISABLE_ARTIFACT nicht gesetzt Wenn 1, deaktivieren Sie das Artifact-Tool in Sitzungen unabhängig von der Admin-Einstellung der Organisation und löschen Sie die *.frame.claudeusercontent.com Egress-Anforderung

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, sobald er sich registriert und seine Startprüfungen abgeschlossen hat. Ab diesem Zeitpunkt ist die Antwort 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:

{
  "status": "ok",
  "runner_id": "ccrunner_...",
  "active_sessions": 2,
  "last_poll_at": "2026-03-31T18:04:11.220Z",
  "last_poll_age_ms": 842
}

Richten Sie Warnungen auf last_poll_age_ms ein, verwenden Sie den Wert aber nicht in einer Liveness-Probe; belassen Sie diese Probe beim HTTP-Statuscode. Der Wert gibt die Zeit seit der letzten erfolgreichen Abfrage an, sodass er auch steigt, während der Runner Anthropic nicht erreichen kann. Sowohl last_poll_at als auch last_poll_age_ms sind null, bis die erste Abfrage erfolgreich ist. Um Abfragen zu erkennen, die von Anfang an fehlschlagen, richten Sie zusätzlich Warnungen auf claude_code_self_hosted_runner_poll_errors_total ein, das unter Prometheus-Metriken aufgeführt 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:

Serie Hinweise
claude_code_self_hosted_runner_info{runner_id,version,client_label} Immer 1; nützlich für die Inventarisierung der Flotte und die Erkennung von Versionsabweichungen
claude_code_self_hosted_runner_capacity Konfigurierter Wert von --capacity
claude_code_self_hosted_runner_active_sessions Aktuell laufende Sitzungen
claude_code_self_hosted_runner_locked_account{email} Vorhanden, sobald der Runner an einen Benutzer gebunden wurde und ein Sitzungs-Token mit einem act.email-Claim ausgestellt wurde. Auf einem Runner, der an einen Claude Tag-Agenten gebunden ist, fehlt die Serie, da dessen Sitzungs-Token kein act.email enthalten. Der Labelwert ist die E-Mail-Adresse des Kontos; wenn Ihr Metrikspeicher allgemein lesbar ist, verwerfen oder hashen Sie das Label beim Scrapen, zum Beispiel mit Prometheus metric_relabel_configs.
claude_code_self_hosted_runner_last_poll_age_seconds Sekunden seit dem letzten erfolgreichen Poll. Alarmieren Sie bei einem Wert über 60.
claude_code_self_hosted_runner_poll_errors_total{error_kind} Kumulierte PollWork-Fehler nach Art: transport, timeout, 5xx, 429 oder 4xx. Alle fünf Serien sind ab Prozessstart vorhanden; alarmieren Sie bei rate(...[5m]) > 0.
claude_code_self_hosted_runner_sessions_started_total{client_platform} Über die Lebensdauer des Runners gestartete Kindprozesse von Sitzungen, eine Serie pro Sitzungsursprung wie web_claude_ai, ios, android, desktop_app oder claude_code_cli, oder unknown, wenn der Server keinen Ursprung gesendet hat. Slack-Sitzungen tragen je nach der Slack-Integration, die sie erstellt hat, entweder claude_in_slack oder claude-in-slack; erfassen Sie daher beide mit einem Regex-Selektor wie {client_platform=~"claude[-_]in[-_]slack"}. Verwenden Sie sum() für die Gesamtsumme der Flotte.
claude_code_self_hosted_runner_sessions_completed_total{client_platform} Sitzungen, die sauber beendet wurden, gleich gelabelt. Weiter gefasst als ein einfacher sauberer Exit: Was hier zählt, finden Sie unter Semantik der Zähler für den Sitzungslebenszyklus.
claude_code_self_hosted_runner_sessions_failed_total{client_platform} Sitzungen, die mit einem Fehler endeten, gleich gelabelt. Gleicher Vorbehalt: siehe Semantik der Zähler für den Sitzungslebenszyklus.
claude_code_self_hosted_runner_sessions_interrupted_total{client_platform} Sitzungen, die der Runner aus einem betrieblichen Grund statt wegen eines Sitzungsergebnisses beendet hat, gleich gelabelt. Siehe Semantik der Zähler für den Sitzungslebenszyklus.
claude_code_self_hosted_runner_initializing_sessions Sitzungen, die sich aktuell in der Init-Phase befinden, von der Zuweisung bis zum Init-Ereignis des Kindprozesses
claude_code_self_hosted_runner_session_init_duration_seconds Histogramm der Init-Dauern von Sitzungen
claude_code_self_hosted_runner_session_init_errors_total Sitzungen, die vor Erreichen von Init fehlgeschlagen sind: ein Fehler im Checkout-Hook, bei der Git-Vorbereitung, ein Token-Problem oder ein Absturz des Kindprozesses vor Init
claude_code_self_hosted_runner_session_start_hook_errors_total SessionStart-Hooks, die ein Fehlerergebnis gemeldet haben, einer pro fehlgeschlagener Hook-Ausführung
claude_code_self_hosted_runner_session_idle_seconds{session_id,client_platform} Gauge pro Sitzung mit den Sekunden, seit die Sitzung inaktiv wurde. Nützlich, um Sitzungen zu beenden, die an einer unbeantworteten Berechtigungsabfrage hängen.

Der Orchestrator stellt seine eigenen Serien unter GET /metrics auf demselben Port wie sein /healthz bereit:

Serie Hinweise
claude_code_self_hosted_orchestrator_info{version,pool_id,orchestrator_uuid,hostname} Immer 1
claude_code_self_hosted_orchestrator_connected 1, wenn der letzte Poll erfolgreich war; fällt nach jedem fehlgeschlagenen Poll auf 0, unabhängig von der Art des Fehlers
claude_code_self_hosted_orchestrator_last_poll_age_seconds Sekunden seit dem letzten Poll-Versuch, ob erfolgreich oder fehlgeschlagen – anders als die gleichnamige Metrik des Runners, die ab dem letzten Erfolg misst; kombinieren Sie sie mit connected, um fehlschlagende Polls zu erkennen. Die Poll-Schleife des Orchestrators wartet auf die Hook-Ausführung; alarmieren Sie daher oberhalb von --hook-timeout plus einer Marge, bei Standardwerten etwa 90 Sekunden, statt pauschal bei 60.
claude_code_self_hosted_orchestrator_poll_errors_total{error_kind} Kumulierte PollSpawnHints-Fehler nach Art: transport, timeout, 5xx, 429 oder 4xx. Alle fünf Serien sind ab Prozessstart vorhanden; alarmieren Sie bei rate(...[5m]) > 0.
claude_code_self_hosted_orchestrator_queue_pending_sessions Spawn-Anfragen, die aktuell übernommen werden können
claude_code_self_hosted_orchestrator_queue_backing_off_sessions Spawn-Anfragen im Backoff für Wiederholungsversuche nach einem wiederholbaren Hook-Fehler
claude_code_self_hosted_orchestrator_queue_circuit_broken_sessions Sitzungen, deren Start blockiert ist. Jede bleibt blockiert, bis ein Benutzer ihr eine neue Nachricht sendet oder ein Owner sie über den Tab Activity der Umgebung erneut versucht. Der Wert kann über null bleiben, nachdem Sie die Ursache behoben haben. Alarmieren Sie bei einem Wert über null.
claude_code_self_hosted_orchestrator_pool_pending_sessions Gesamtzahl der Sitzungen, die in dieser Umgebung auf einen Runner warten. Umgebungsweites Aggregat, identisch auf jeder Orchestrator-Instanz: Verwenden Sie über Instanzen hinweg MAX statt SUM.
claude_code_self_hosted_orchestrator_pool_active_sessions Sitzungen, die aktuell einem aktiven Runner in dieser Umgebung zugewiesen sind. Umgebungsweites Aggregat, identisch auf jeder Orchestrator-Instanz: Verwenden Sie über Instanzen hinweg MAX statt SUM.
claude_code_self_hosted_orchestrator_spawn_hooks_total{result} Kumulierte Ergebnisse des spawn-runner-Hooks: ok, retryable, non_retryable. Zählt Hook-Aufrufe des Orchestrators, nicht die von den Runnern gestarteten Kindprozesse von Sitzungen: nicht vergleichbar mit sessions_started_total, da eine Kapazität über eins, Warm-Pools und für dieselbe Sitzung erneut gestartete Runner die beiden Werte auseinanderlaufen lassen.
claude_code_self_hosted_orchestrator_spawn_hook_duration_seconds Histogramm der Hook-Dauern
claude_code_self_hosted_orchestrator_warm_hints_dispatched_total Seit Prozessstart versendete Standby-Spawn-Anfragen
claude_code_self_hosted_orchestrator_session_queue_wait_seconds Histogramm der Sekunden, die jede Sitzung in der Warteschlange gewartet hat, bevor der Orchestrator sie zum Starten übernommen hat, erfasst anhand des Wartezeit-Zeitstempels, den die Steuerungsebene mit der Spawn-Anfrage jeder Sitzung sendet. Verwenden Sie es für Alarme auf p50/p99 der Wartezeit. Starts zum Vorwärmen werden nicht erfasst.
claude_code_self_hosted_orchestrator_clock_skew_seconds Uhrenabweichung lokal minus Server; diagnostisch, vorhanden, sobald gemessen
claude_code_self_hosted_orchestrator_scm_connector_connected 1, wenn der WebSocket des SCM-Konnektors geöffnet ist; 0 während des Verbindungsaufbaus oder im Backoff. Fehlt, wenn --scm-connector-host nicht gesetzt ist.
claude_code_self_hosted_orchestrator_scm_connector_requests_forwarded_total Kumulierte HTTP-Anfragen, die seit Prozessstart an den konfigurierten SCM-Host weitergeleitet wurden. Fehlt, wenn --scm-connector-host nicht gesetzt ist.

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:

# Example Prometheus Operator PodMonitor for the Claude Code self-hosted
# runner + orchestrator. Adjust the namespace and label selectors to match
# your deployment. Both the runner and the orchestrator serve /metrics on
# their --health-port (default 8080).
apiVersion: monitoring.coreos.com/v1
kind: PodMonitor
metadata:
  name: claude-code-self-hosted-runner
  namespace: monitoring
spec:
  namespaceSelector:
    matchNames:
      - claude-runners
  selector:
    matchExpressions:
      # Matches the runner Deployment from the Kubernetes recipe, plus any
      # on-demand runner Jobs and orchestrator pods you label the same way
      # and give a named 'health' containerPort.
      - key: app.kubernetes.io/part-of
        operator: In
        values: [claude-code-self-hosted-runner]
  podMetricsEndpoints:
    - port: health
      path: /metrics
      interval: 30s

Beispiel-Alarmregeln

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

# Example Prometheus alert rules for the Claude Code self-hosted runner
# + orchestrator. Tune thresholds for your fleet size and SLOs.
groups:
  - name: claude-code-self-hosted-runner
    rules:
      - alert: ClaudeRunnerPollStale
        expr: claude_code_self_hosted_runner_last_poll_age_seconds > 60
        for: 2m
        labels: {severity: warning}
        annotations:
          summary: "Runner {{ $labels.pod }} has not polled in >60s"
      - alert: ClaudeRunnerVersionDrift
        expr: count(count by (version) (claude_code_self_hosted_runner_info)) > 1
        for: 30m
        labels: {severity: info}
        annotations:
          summary: "Runners are running mixed versions"
      - alert: ClaudeRunnerInitErrorsHigh
        expr: sum by (namespace) (increase(claude_code_self_hosted_runner_session_init_errors_total[10m])) > 3
        for: 5m
        labels: {severity: warning}
        annotations:
          summary: "Sessions are failing before init (checkout hook / git / token / pre-init crash)"
      - alert: ClaudeRunnerPollErrors
        expr: sum by (pod) (rate(claude_code_self_hosted_runner_poll_errors_total[5m])) > 0
        for: 2m
        labels: {severity: warning}
        annotations:
          summary: "Runner {{ $labels.pod }}: PollWork failing ({{ $value | humanize }}/s over 5m)"
      - alert: ClaudeRunnerSessionStartHookErrors
        expr: sum by (namespace) (increase(claude_code_self_hosted_runner_session_start_hook_errors_total[10m])) > 3
        for: 5m
        labels: {severity: warning}
        annotations:
          summary: "SessionStart hooks are failing"

  - name: claude-code-self-hosted-orchestrator
    rules:
      - alert: ClaudeOrchestratorDisconnected
        expr: claude_code_self_hosted_orchestrator_connected == 0
        for: 2m
        labels: {severity: critical}
        annotations:
          summary: "Orchestrator {{ $labels.pod }} cannot reach the Anthropic control plane"
      - alert: ClaudeOrchestratorPollStale
        expr: claude_code_self_hosted_orchestrator_last_poll_age_seconds > 90
        for: 2m
        labels: {severity: warning}
        annotations:
          summary: "Orchestrator {{ $labels.pod }} has not polled in >90s (poll loop waits on hook execution)"
      - alert: ClaudeOrchestratorCircuitBroken
        expr: max by (namespace) (claude_code_self_hosted_orchestrator_queue_circuit_broken_sessions and on (instance) max_over_time(claude_code_self_hosted_orchestrator_connected[2m]) == 1) > 0
        for: 1m
        labels: {severity: critical}
        annotations:
          summary: "Sessions blocked from spawning: {{ $value }}. Read each one's error in the Activity tab, fix the cause, then select Retry"
      - alert: ClaudeOrchestratorPollErrors
        expr: sum by (pod) (rate(claude_code_self_hosted_orchestrator_poll_errors_total[5m])) > 0
        for: 2m
        labels: {severity: warning}
        annotations:
          summary: "Orchestrator {{ $labels.pod }}: PollSpawnHints failing ({{ $value | humanize }}/s over 5m)"
      - alert: ClaudeOrchestratorSpawnHookFailing
        expr: sum by (pod) (increase(claude_code_self_hosted_orchestrator_spawn_hooks_total{result!="ok"}[5m])) > 3
        for: 5m
        labels: {severity: warning}
        annotations:
          summary: "Orchestrator {{ $labels.pod }}: >3 spawn-runner hook failures in 5m"

Bei verlorenen Runnern und wartenden Sitzungen alarmieren

Um benachrichtigt zu werden, wenn Runner verloren gehen, Sitzungen warten oder der Orchestrator ausgefallen ist, laden Sie diese Prometheus-Alarmregeln zusätzlich zu den Beispiel-Alarmregeln:

  • Feste Flotte: ClaudeRunnersBelowFloor
  • On-Demand-Runner: ClaudeOrchestratorSessionsWaiting, ClaudeOrchestratorQueueWaitHigh und ClaudeOrchestratorAbsent

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:

groups:
  # Fixed fleets only. With on-demand runners the count follows demand,
  # so ClaudeRunnersBelowFloor would fire whenever demand is low.
  - name: claude-code-self-hosted-fixed-fleet-capacity
    rules:
      - alert: ClaudeRunnersBelowFloor
        expr: (count(claude_code_self_hosted_runner_info{namespace="claude-runners"}) or vector(0)) < 2
        for: 10m
        labels: {severity: critical, namespace: claude-runners}
        annotations:
          summary: "Runners registered and scraped: {{ $value }}, below the floor. Check the runner workloads first, then the scrape targets if all are running."
  • 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:

groups:
  # On-demand runners only. Needs no edit for the namespace.
  - name: claude-code-self-hosted-on-demand-capacity
    rules:
      - alert: ClaudeOrchestratorSessionsWaiting
        expr: |
          max by (namespace) (
            claude_code_self_hosted_orchestrator_pool_pending_sessions
            and on (instance)
            max_over_time(claude_code_self_hosted_orchestrator_connected[2m]) == 1
          ) > 0
        for: 10m
        labels: {severity: warning}
        annotations:
          summary: "Sessions waiting for a runner: {{ $value }}, above the threshold for 10 minutes. Check claude_code_self_hosted_orchestrator_spawn_hooks_total by result, then runner workloads that don't start."
      - alert: ClaudeOrchestratorQueueWaitHigh
        expr: |
          histogram_quantile(0.99, sum by (namespace, le) (
            rate(claude_code_self_hosted_orchestrator_session_queue_wait_seconds_bucket[10m])
          )) > 160
        for: 5m
        labels: {severity: warning}
        annotations:
          summary: "Over 1% of queue waits in the last 10 minutes exceeded 160 seconds. Check whether ClaudeOrchestratorDisconnected is firing, then claude_code_self_hosted_orchestrator_spawn_hooks_total by result and claude_code_self_hosted_orchestrator_spawn_hook_duration_seconds."
  • 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

Alarmieren, wenn der Orchestrator ausgefallen ist

Um zu erfahren, dass der Orchestrator selbst ausgefallen ist, laden Sie ClaudeOrchestratorAbsent. Der Alarm wird ausgelöst, wenn 5 Minuten lang kein Orchestrator im Namespace gescrapt wurde:

groups:
  # On-demand runners only. Replace claude-runners with the orchestrator's namespace.
  - name: claude-code-self-hosted-on-demand-orchestrator
    rules:
      - alert: ClaudeOrchestratorAbsent
        expr: absent(claude_code_self_hosted_orchestrator_connected{namespace="claude-runners"})
        for: 5m
        labels: {severity: critical}
        annotations:
          summary: "No orchestrator has been scraped for 5 minutes. If it's down, no on-demand runner starts, and sessions wait. Check the orchestrator workload first, then its scrape target if it's running."
  • Namespace: Ersetzen Sie claude-runners durch den Namespace des Orchestrators, und kopieren Sie den Alarm für jeden weiteren Namespace, in dem ein Orchestrator läuft. Wenn Ihre Ziele kein namespace-Label haben, entfernen Sie den Matcher, da der Alarm sonst nach 5 Minuten ausgelöst wird und aktiv bleibt.
  • Prometheus-Server, die den Orchestrator nicht scrapen: Lassen Sie den Alarm aus deren Regeldateien weg, da er auf einem solchen Server nach 5 Minuten ausgelöst wird und aktiv bleibt
  • Verlassen Sie sich nicht auf die anderen Alarme des Orchestrators: Sie lesen Metriken, die der Orchestrator selbst bereitstellt. ClaudeOrchestratorSessionsWaiting, ClaudeOrchestratorQueueWaitHigh und die Beispiel-Alarmregeln des Orchestrators werden alle innerhalb von etwa 10 Minuten nach dem Ausfall des Orchestrators nicht mehr ausgelöst.

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:

sum by (ccr_session_id) (claude_code_cost_usage_total)
and on (ccr_session_id)
label_replace(
  claude_code_self_hosted_runner_session_idle_seconds > 600,
  "ccr_session_id", "cse_$1", "session_id", "session_(.*)"
)

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:

Ziel Verwenden
Durchsatz claude_code_self_hosted_orchestrator_spawn_hooks_total{result="ok"}, ein Zähler auf dem langlebigen Orchestrator, der pro erfolgreichem spawn-runner-Hook einmal erhöht wird und unter rate() aussagekräftig bleibt. Er zählt Hook-Aufrufe statt Sitzungen, sodass Vorwärmen und wiederholte Starts für dieselbe Sitzung ihn von den Sitzungszahlen abweichen lassen.
Auslastung sum(claude_code_self_hosted_runner_active_sessions) im Verhältnis zu sum(claude_code_self_hosted_runner_capacity), beides Gauges, die bei jedem Scrape unabhängig von der Lebensdauer des Runners gültig sind
Rückstau claude_code_self_hosted_orchestrator_pool_pending_sessions für die Warteschlangentiefe und claude_code_self_hosted_orchestrator_queue_circuit_broken_sessions mit einem Alarm bei einem Wert über null
Fehler claude_code_self_hosted_runner_sessions_failed_total, nach bestem Bemühen: Echte Abstürze nach dem Start erhöhen ihn, und rate() ist auf Runnern aussagekräftig, die ihre Sitzungen mit einem --drain-grace-sec-Wert über 0 überdauern. Eine One-Shot-Umgebung hat dasselbe Problem mit dem Scrape-Fenster wie die anderen Endzähler; betrachten Sie daher jeden Wert ungleich null, den Sie sehen, als untersuchungswürdig. Fehler vor dem Start, etwa ein Fehler im Checkout-Hook, bei der Git-Vorbereitung oder ein Token-Problem, erscheinen nur in session_init_errors_total.

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