Riferimento per ambienti self-hosted
Riferimento completo per il runner self-hosted e l'orchestrator: flag CLI, variabili d'ambiente e metriche Prometheus.
Gli ambienti self-hosted sono in beta pubblica sui piani Team ed Enterprise; un Owner li abilita attivando Allow self-hosted environments nella pagina di amministrazione Cloud environments. Questa pagina è il riferimento per flag e metriche; consultare la guida rapida per la configurazione e Deploy to production per le ricette della flotta.
Questa pagina è il riferimento per i due processi che eseguite in un ambiente self-hosted: il runner, che esegue le sessioni cloud di Claude Code sui vostri host, e l'orchestrator di autoscaling opzionale, che avvia i runner mentre le sessioni si accodano. Ognuno ha la propria tabella di flag. Entrambi vengono eseguiti su host Linux o macOS, per i quali i valori predefiniti come /workspace e ~/.claude sono presupposti. Eseguite claude self-hosted-runner --help per l'elenco autorevole sulla vostra versione installata.
Le serie di metriche e alcuni campi API utilizzano ancora pool per quello che queste pagine chiamano un ambiente; entrambi i termini denominano la stessa cosa. L'ID dell'ambiente è il campo pool_id, con la forma ccpool_...: ovunque queste pagine mostrino un identificatore pool, esso denomina l'ambiente. I flag CLI e le variabili d'ambiente lo scrivono come environment, come in --environment-secret-file; i nomi deprecati pool continuano a funzionare, come la riga --environment-secret-file descrive.
Flag CLI del runner
La maggior parte dei flag ha una variabile d'ambiente corrispondente. Quando entrambi sono impostati, il flag ha la precedenza. I flag di durata accettano minuti o secondi sulla CLI, ma la variabile d'ambiente associata è sempre in millisecondi, indicata dal suffisso _MS, e la colonna Default mostra l'unità del flag: --exit-if-unused-min 10 è equivalente a SELF_HOSTED_RUNNER_IDLE_SHUTDOWN_MS=600000, e un valore Helm come SELF_HOSTED_RUNNER_STARTUP_TIMEOUT_MS: "15" significa 15 millisecondi, non il valore predefinito di 15 minuti.
| Flag | Env var | Default | Description |
|---|---|---|---|
--api-url <url> |
none | https://api.anthropic.com |
URL base dell'API. Eseguire l'override solo per i test. |
--base-dir <path> |
SELF_HOSTED_RUNNER_BASE_DIR |
/workspace; nessuno su Windows |
Directory per i checkout dei repository e le directory di lavoro per sessione. Il runner necessita dell'accesso in scrittura a questo percorso o al suo genitore. Il runner crea la directory all'avvio e esce con cannot create or write to base directory quando non riesce a crearla o scrivervi. Prima della v2.1.225, il runner creava la directory quando la prima sessione iniziava, quindi un percorso inutilizzabile causava il fallimento delle sessioni piuttosto che dell'avvio. Su Windows, che non è un host runner supportato, non c'è un valore predefinito: il runner esce all'avvio a meno che non passi il flag o imposti la variabile. Usa lo stesso valore su ogni runner in un ambiente. Vedi Keep the base directory and capacity identical across runners. |
--capacity <n> |
none | 1 |
Numero massimo di sessioni simultanee che questo runner gestisce. Tutte le sessioni appartengono allo stesso owner bloccato. Usa lo stesso valore su ogni runner in un ambiente; vedi Keep the base directory and capacity identical across runners. |
--client-label <label> |
SELF_HOSTED_RUNNER_CLIENT_LABEL |
l'hostname dell'host | Etichetta che il runner invia quando si registra. Il runner lo segnala anche come etichetta client_label di claude_code_self_hosted_runner_info. Richiede Claude Code v2.1.248 o successivo. |
--configure-git |
SELF_HOSTED_RUNNER_CONFIGURE_GIT=1 |
off | All'avvio, scrivi l'identità git globale, abilita la firma dei commit Anthropic, attiva la negoziazione push di git e installa hook di commit che aggiungono un trailer Co-authored-by:. La negoziazione push richiede Claude Code v2.1.257 o successivo. Vedi Configure git. |
--confine-repo-settings <mode> |
SELF_HOSTED_RUNNER_CONFINE_REPO_SETTINGS |
warn |
Imposta la modalità della guardia che contrassegna una sessione quando le impostazioni impegnate di un repository tentano di concedere accesso in scrittura o lettura al di fuori dello spazio di lavoro della sessione, impostare variabili d'ambiente o eseguire l'override della postura sandbox o hooks dell'operatore, come sandbox.enabled: false o disableAllHooks. Il valore predefinito warn registra la violazione e avvia comunque la sessione, enforce rifiuta la sessione e off disabilita la scansione. Vedi Harden your deployment. |
--debug-token-dir <path> |
SELF_HOSTED_RUNNER_DEBUG_TOKEN_DIR |
unset | Scrivi i token live su disco per l'ispezione. Solo debug; non usare in produzione. |
--defer-shutdown-max-min <n> |
SELF_HOSTED_RUNNER_DEFER_SHUTDOWN_MAX_MS |
0 |
Al primo SIGTERM o SIGINT, continua a servire le sessioni già collegate invece di drenare, quindi rilascia tutto ciò che è ancora collegato N minuti dopo e esci. Aumenta il timeout di arresto del tuo host prima di impostare questo. Vedi Defer the drain past the first signal. 0 disabilita. Richiede Claude Code v2.1.238 o successivo. |
--drain-grace-sec <n> |
SELF_HOSTED_RUNNER_DRAIN_GRACE_MS |
0 |
Fino a quando il runner riceve un segnale di arresto o raggiunge il suo tempo di ritiro, controlla quando il runner esce dopo che le sue sessioni attive finiscono: 0 esce immediatamente senza polling per altri, e un valore positivo mantiene il runner attivo e ri-polling della coda dell'owner bloccato per quel numero di secondi, al costo dell'isolamento del contenitore per sessione descritto nella sezione hardening. Dopo un primo segnale che hai differito con --defer-shutdown-max-min, il runner esce non appena non contiene sessioni, indipendentemente da quello che imposti qui. |
--drain-marker-file <path> |
SELF_HOSTED_RUNNER_DRAIN_MARKER_FILE |
unset | File marcatore che il tuo host scrive per annunciare un drenaggio elegante prima di inviare SIGTERM. Quando il file esiste all'inizio del drenaggio, il runner segnala la sua uscita ad Anthropic come un drenaggio dell'host piuttosto che un semplice segnale di arresto. Il drenaggio stesso, inclusa la sospensione --drain-wait-sec, funziona allo stesso modo senza il flag. Nomina un percorso su un filesystem locale che le sessioni non possono scrivere. Richiede Claude Code v2.1.271 o successivo. |
--drain-wait-sec <n> |
SELF_HOSTED_RUNNER_DRAIN_WAIT_MS |
0 |
Una volta che il drenaggio inizia, che è su SIGTERM a meno che non imposti --defer-shutdown-max-min, attendi fino a N secondi affinché il turno in volo di ogni sessione e i compiti in background finiscano prima di terminare il figlio. Durante questa attesa, il runner conta un compito in background che ha appena finito come ancora in esecuzione fino a quando il turno di follow-up che legge il suo risultato inizia, per al massimo la finestra SELF_HOSTED_RUNNER_BG_RESULT_GRACE_MS. |
--environment-secret-file <path> |
SELF_HOSTED_RUNNER_ENVIRONMENT_SECRET |
required | Percorso a un file contenente il segreto dell'ambiente, o, per i runner generati dall'orchestrator, il JWT del work-order monouso. SELF_HOSTED_RUNNER_ENVIRONMENT_SECRET porta il valore del segreto direttamente, non un percorso di file. Il flag --pool-secret-file più vecchio e la variabile SELF_HOSTED_RUNNER_POOL_SECRET ancora funzionano e stampano un avviso di deprecazione su stderr; le build del runner del programma di anteprima più vecchie di 2.1.216 riconoscono solo quei nomi più vecchi. |
--exec-path <path> |
SELF_HOSTED_RUNNER_EXEC_PATH |
own binary | File binario o script wrapper da generare per ogni sessione. Vedi Wrapper scripts. |
--exit-if-unused-min <n> |
SELF_HOSTED_RUNNER_IDLE_SHUTDOWN_MS |
0 |
Esci dopo N minuti di polling senza lavoro mai assegnato, per il scale-down dell'autoscaler. 0 disabilita. |
--git-host-rewrite <from>=<to> |
none | unset | Riscrivi gli URL di origine https://<from>/... a https://<to>/... prima della clonazione, per DNS a orizzonte diviso. Ripetibile; solo flag. |
--git-ssh-rewrite <host> |
none | unset | Riscrivi gli URL di origine https://<host>/... a git@<host>:... prima della clonazione, per host git solo SSH. Ripetibile; solo flag. |
--health-port <port> |
SELF_HOSTED_RUNNER_HEALTH_PORT |
8080 |
Porta per il listener /healthz e /metrics. Imposta 0 per disabilitare. |
--hooks-dir <path> |
SELF_HOSTED_RUNNER_HOOKS_DIR |
unset | Directory degli script hook del ciclo di vita. Vedi Lifecycle hooks. |
--host-config-snapshot <mode> |
SELF_HOSTED_RUNNER_HOST_CONFIG_SNAPSHOT |
disk |
Dove il runner mantiene lo snapshot di avvio della directory di configurazione dell'host che semina ogni sessione da. disk copia lo snapshot in una directory di proprietà del runner sotto --base-dir e, all'inizio di ogni sessione, verifica ogni file rispetto a un digest in memoria. Se un file nella copia è stato modificato, la sessione fallisce e il runner rifiuta le sessioni fino a quando non lo riavvii. memory mantiene l'intero snapshot sull'heap, limitato a 64 MiB; oltre il limite, le sessioni iniziano senza configurazione dell'host e mostrano un avviso che dice così. Quando il runner non può scrivere lo snapshot del disco, registra l'errore e usa memory per quella esecuzione. Richiede Claude Code v2.1.271 o successivo. |
--kill-session-after-min <n> |
SELF_HOSTED_RUNNER_MAX_LIFETIME_MS |
0 |
Limita una sessione a N minuti di tempo reale, come limite di sicurezza per le sessioni bloccate. Su v2.1.260 o successivo, il runner rilascia una sessione che raggiunge il limite in modo che possa riprendere al prossimo messaggio dell'utente, e la termina solo se è ancora sul runner quando la finestra di grazia SELF_HOSTED_RUNNER_MAX_LIFETIME_GRACE_MS finisce. Prima della v2.1.260, il runner terminava la sessione al limite. Vedi Some sessions don't count as idle per i dettagli e come scegliere un valore. 0 disabilita. |
--lock-to-account <id> |
SELF_HOSTED_RUNNER_LOCK_TO_ACCOUNT |
unset | Pre-blocca il runner a un account specifico all'avvio invece di bloccare alla prima sessione. Accetta un indirizzo email o un ID user_... nell'organizzazione dell'ambiente. Un runner pre-bloccato non raccoglie mai sessioni del canale Claude Tag, che non hanno account. |
--log-file <path> |
SELF_HOSTED_RUNNER_LOG_FILE |
unset | Specchia i log del runner in un file oltre a stdout e stderr, creato con permessi 0600. Richiesto per self-hosted-runner doctor per accodare i log localmente. |
--log-level <level> |
none | info |
info o debug |
--post-session-hook-timeout-sec <n> |
SELF_HOSTED_RUNNER_POST_SESSION_HOOK_TIMEOUT_MS |
60 |
Budget per l'hook post-session alla fine di ogni sessione, incluso l'arresto del runner |
--proxy-authorization-command <command> |
SELF_HOSTED_RUNNER_PROXY_AUTHORIZATION_COMMAND |
unset | Comando shell che il runner esegue per ogni connessione al tuo proxy di uscita, usando il suo stdout ritagliato come valore dell'intestazione Proxy-Authorization. Richiede HTTPS_PROXY o HTTP_PROXY, e non può essere combinato con --proxy-authorization-file. Vedi Authenticate to an egress proxy. Richiede Claude Code v2.1.238 o successivo. |
--proxy-authorization-file <path> |
SELF_HOSTED_RUNNER_PROXY_AUTHORIZATION_FILE |
unset | File che il runner legge per ogni connessione al tuo proxy di uscita, usando i suoi contenuti ritagliati come valore dell'intestazione Proxy-Authorization. Usa questo flag per un token che un altro processo ruota in posizione. Porta gli stessi requisiti di --proxy-authorization-command, e non può essere combinato con esso. Vedi Authenticate to an egress proxy. Richiede Claude Code v2.1.238 o successivo. |
--push-outcome-on-release |
SELF_HOSTED_RUNNER_PUSH_OUTCOME_ON_RELEASE |
off | Alla fine di una sessione avviata dal runner come un drenaggio o una versione inattiva, esegui il push dei rami di risultato tracciati a origin prima di eliminare lo spazio di lavoro, in modo che i commit in volo sopravvivano a un riavvio. Best-effort; aggiunge 30 secondi al budget di arresto, e richiede git 2.29 o più recente per riprendere dal ramo sottoposto a push. Limita l'accesso push ai ref claude/* prima di abilitare; vedi Resumed sessions lose unpushed work. I repository estratti tramite un hook del ciclo di vita checkout non vengono sottoposti a push; fai uno snapshot di quelli dall'hook post-session invece. |
--release-idle-session-min <n> |
SELF_HOSTED_RUNNER_SESSION_IDLE_MS |
0 |
Rilascia uno slot di sessione dopo N minuti di inattività una volta che un turno finisce o la sessione attende l'azione dell'utente. Una sessione che è ancora a metà turno, inclusa una che contiene un compito in background che non finisce mai o un'approvazione richiesta dall'interno di una chiamata di strumento in esecuzione, non conta come inattiva; abbina con --kill-session-after-min come backstop duro. Dopo che il compito in background di una sessione finisce, il runner considera la sessione occupata fino a quando il turno di follow-up che legge il risultato inizia, per al massimo la finestra SELF_HOSTED_RUNNER_BG_RESULT_GRACE_MS. Fino a quando il runner riceve un segnale di arresto o raggiunge il suo tempo di ritiro, un rilascio che lascia il runner senza sessioni attive avvia lo stesso percorso di uscita di un drenaggio normale, governato da --drain-grace-sec. Dopo un primo segnale che hai differito con --defer-shutdown-max-min, il runner esce non appena un rilascio lo lascia senza sessioni. 0 disabilita. |
--remove-session-state [bool] |
SELF_HOSTED_RUNNER_REMOVE_SESSION_STATE |
off | Rimuovi le directory per sessione di una sessione sotto <base-dir>/_sessions/ quando la sessione termina su questo runner, indipendentemente dall'esito. Reuse a pre-warmed checkout descrive cosa contengono e chi può leggerli quando rimangono. La rimozione è best-effort: le directory per sessione rimangono in posizione quando il runner viene ucciso o raggiunge la scadenza di drenaggio prima che la pulizia venga eseguita. Con il flag attivo, il log di debug di una sessione fallita o interrotta non viene mantenuto su disco. Richiede Claude Code v2.1.268 o successivo. |
--retire-at <epoch-seconds> |
SELF_HOSTED_RUNNER_RETIRE_AT |
unset | Ritira il runner a un timestamp Unix assoluto in secondi, per l'infrastruttura che uccide il runner a un'ora nota; Runner lifecycle descrive la sequenza di rilascio e come dimensionare il margine. I valori prima del 2001 o dopo l'anno 5138 vengono rifiutati dal flag e ignorati dalla variabile d'ambiente. |
--session-stop-grace-sec <n> |
SELF_HOSTED_RUNNER_SESSION_STOP_GRACE_MS |
5 |
Quanto tempo aspettare affinché il processo Claude esca correttamente dopo la fine di una sessione, prima di forzare l'uccisione. Aumenta il valore se gli hook SessionEnd del figlio hanno bisogno di più tempo. |
--startup-timeout-min <n> |
SELF_HOSTED_RUNNER_STARTUP_TIMEOUT_MS |
15 |
Rilascia uno slot di sessione se il figlio non ha segnalato che si è inizializzato entro N minuti dalla generazione. Cancellato dal segnale di init del figlio sul canale di attività, non dall'output ordinario, dopo di che --release-idle-session-min prende il sopravvento. 0 disabilita. |
--trust-workspace [bool] |
SELF_HOSTED_RUNNER_TRUST_WORKSPACE |
on | Semina la fiducia persistente per i percorsi del repository di ogni sessione in modo che permissions.allow e additionalDirectories impegnati nel repo siano onorati. Imposta false per eliminare le concessioni di autorizzazione impegnate nel repo e configurare le regole di autorizzazione nella settings.json della configurazione dell'host; le impostazioni sandbox.* impegnate nel repository si applicano comunque in entrambi i casi, motivo per cui la guardia repo-settings le scansiona indipendentemente da questo flag. |
--use-anthropic-git-proxy |
CLAUDE_RUNNER_USE_GIT_PROXY=1 |
off | Clona tramite il proxy git di Anthropic invece dell'autenticazione git gestita dal cliente. Richiede --capacity 1 e git 2.32 o più recente; il runner rifiuta di avviarsi altrimenti. Sostituisce i flag di riscrittura. |
La maggior parte dei flag di durata ha un massimo, scelto per mantenere ogni timeout entro il limite del timer a 32 bit del runtime di circa 24,85 giorni. I flag --*-min hanno un limite di 10080 minuti, 7 giorni; --drain-grace-sec a 604800 secondi, anche 7 giorni; e --drain-wait-sec a 86400 secondi, 24 ore. --session-stop-grace-sec e --post-session-hook-timeout-sec non hanno limiti. Superare un limite si comporta diversamente per superficie:
- Flag: l'avvio fallisce con un errore.
- Variabile d'ambiente: il runner fissa il valore al limite del timer piuttosto che rifiutarlo.
Flag CLI dell'orchestrator
Il sottocomando self-hosted-runner orchestrator, che genera runner on-demand, accetta --api-url, --environment-secret-file, --hooks-dir, --health-port e --log-level con gli stessi valori predefiniti del runner e, dove il flag del runner ne ha uno, la stessa variabile d'ambiente, tranne che --hooks-dir è obbligatorio e deve contenere un hook spawn-runner. Accetta anche i suoi flag:
| Flag | Default | Description |
|---|---|---|
--hook-concurrency <n> |
4 |
Numero massimo di hook spawn-runner in esecuzione in parallelo. Limita anche quante richieste di spawn vengono rivendicate per polling. |
--hook-timeout <sec> |
60 |
Termina l'albero dei processi dell'hook dopo questo numero di secondi. Il timeout più la sua grazia di 5 secondi deve rimanere al di sotto di --expected-spawn-seconds; l'orchestrator lo applica all'avvio. |
--expected-spawn-seconds <sec> |
120 |
Tempo di avvio p99 previsto per i runner generati, nell'intervallo applicato dal server da 10 a 3600. Inviato ad ogni polling come il lease lato server; se nessun runner si registra prima che trascorra, la sessione viene ri-offerta con un ID ordine nuovo. Tutte le repliche devono condividere questo valore. |
--min-idle <n> |
0 |
Mantieni almeno N slot di sessione inattivi liberi generando proattivamente runner di standby. 0 disabilita il pre-riscaldamento. Abbina con il --exit-if-unused-min del runner in modo che i runner di standby in eccesso si riprendano. |
--debug-dir <path> |
unset | Scrivi il work order e lo stderr dell'hook di ogni richiesta di spawn su disco. Solo debug; non impostare mai in produzione. |
Flag del connettore SCM
L'orchestrator può mantenere una connessione WebSocket permanente al piano di controllo di Anthropic in modo che i flussi pre-sessione ospitati, come il selettore di repository e il risolutore di ramo o ref, possano raggiungere un host GitHub Enterprise Server che è instradabile solo dall'interno della tua rete. Il connettore rimane disattivato a meno che non imposti --scm-connector-host.
| Flag | Default | Description |
|---|---|---|
--scm-connector-host <host[:port]> |
unset | Nome host di GitHub Enterprise Server a cui inoltrare le richieste. La porta predefinita è 443. L'impostazione di questo flag abilita il connettore. |
--scm-connector-id <n> |
required with --scm-connector-host |
L'ID numerico della connessione GitHub Enterprise Server della tua organizzazione. Contatta il tuo team di account Anthropic per il valore quando abiliti il connettore. |
--scm-connector-provider <slug> |
ghe |
Segmento di percorso che identifica il provider, corrispondente a ^[a-z0-9-]{1,32}$. |
--scm-connector-ca-file <path> |
unset | Bundle CA aggiuntivo, in formato PEM, per le connessioni TLS all'host GitHub Enterprise Server. |
--scm-connector-host-rewrite <from>=<to_host:to_port> |
unset | Solo per test end-to-end: reindirizza la connessione TCP mantenendo l'intestazione Host e TLS SNI come --scm-connector-host. |
Il connettore si autentica con il segreto dell'ambiente esistente dell'orchestrator e si riconnette automaticamente: con backoff esponenziale su una connessione interrotta, o un ritardo fisso di 30 secondi quando il piano di controllo chiude la connessione perché un'altra replica dell'orchestrator la contiene già.
Impostazioni solo variabili d'ambiente
Queste impostazioni del runner vengono lette solo dall'ambiente e coprono il comportamento che la maggior parte delle distribuzioni lascia al valore predefinito:
| Env var | Default | Description |
|---|---|---|
SELF_HOSTED_RUNNER_BG_RESULT_GRACE_MS |
30000 |
Quanto tempo il runner considera una sessione occupata dopo che un compito in background finisce mentre il turno di follow-up che legge il risultato non è ancora iniziato. Le righe --drain-wait-sec e --release-idle-session-min descrivono dove si applica la tenuta su drenaggio e rilascio inattivo, e Runner lifecycle descrive dove si applica al ritiro --retire-at. 0 o un valore inutilizzabile ricade al valore predefinito, quindi la tenuta non può essere disattivata. Richiede Claude Code v2.1.228 o successivo. |
SELF_HOSTED_RUNNER_HOST_CONFIG_DIR |
~/.claude |
Directory acquisita nello snapshot di avvio del runner e seminata nella CLAUDE_CONFIG_DIR di ogni sessione; le modifiche su disco si applicano dopo un riavvio del runner. L'impostazione della variabile sposta anche dove il runner legge .claude.json per il seeding MCP, quindi impostarla, incluso al suo valore predefinito, trasferisce quella ricerca; punta a una directory vuota per disabilitare completamente il seeding. |
SELF_HOSTED_RUNNER_MAX_LIFETIME_GRACE_MS |
900000 |
Quanto tempo il runner attende dopo che una sessione raggiunge il suo limite --kill-session-after-min, affinché un turno in esecuzione finisca o il rilascio si completi, prima di terminare la sessione |
SELF_HOSTED_RUNNER_SIGKILL_GRACE_MS |
30000 |
Quanto tempo il runner attende che il sistema operativo consegni SIGKILL a un figlio bloccato in I/O non interrompibile prima di uscire lui stesso. Limitato inferiormente a --post-session-hook-timeout-sec più 15 secondi, e 30 in più quando --push-outcome-on-release è impostato, quindi il minimo effettivo è 75 secondi ai valori predefiniti. |
CLAUDE_RUNNER_FETCH_DEPTH |
50 |
Profondità di fetch git per cloni freschi. Imposta un numero intero positivo, o full o 0 per un fetch completo. I repository già presenti nello spazio di lavoro mantengono la loro profondità esistente. |
CLAUDE_RUNNER_SKIP_GIT_VERIFY |
unset | Quando 1, salta il controllo della presenza .git dopo l'esecuzione di un hook checkout. Imposta questo quando il tuo hook materializza una fonte non-git. |
FORCE_AUTOUPDATE_PLUGINS |
unset | Quando 1, consenti ai marketplace dei plugin di auto-aggiornare anche se il binario è bloccato |
CLAUDE_CODE_DISABLE_ARTIFACT |
unset | Quando 1, disabilita lo strumento Artifact nelle sessioni indipendentemente dall'impostazione di amministrazione dell'organizzazione, e elimina il requisito di uscita *.frame.claudeusercontent.com |
Telemetria
I figli della sessione inviano telemetria operativa ad Anthropic a meno che non la disattivi. Nessun codice o contenuto del repository viene inviato. Imposta le variabili di telemetria sul processo del runner; il runner le ri-asserisce dopo aver applicato le variabili d'ambiente fornite dal server, quindi l'impostazione dell'operatore ha sempre la precedenza.
Un controllo è specifico per gli ambienti self-hosted: CLAUDE_CODE_BYOC_ENABLE_DATADOG=1 acconsente alle metriche operative di Datadog, che sono disattivate per impostazione predefinita negli ambienti self-hosted. I controlli generali di telemetria di Claude Code, DISABLE_TELEMETRY, DO_NOT_TRACK, DISABLE_ERROR_REPORTING e CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC, si applicano ai figli della sessione come documentato nel riferimento delle variabili d'ambiente. DISABLE_GROWTHBOOK è correlato ma diverso: impostare DISABLE_GROWTHBOOK=1 disabilita il recupero dei flag di funzionalità, e la telemetria rimane attiva a meno che DISABLE_TELEMETRY non sia anche impostato.
CLAUDE_CODE_ENABLE_TELEMETRY non è correlato: abilita l'esportazione OpenTelemetry al tuo collettore, come descritto in Monitoring, e non controlla l'analittica di Anthropic.
Endpoint di salute
Il runner serve GET /healthz sulla porta di salute configurata. La risposta è 200 OK ogni volta che il processo è attivo, qualunque stato sia il ciclo di polling, quindi un probe HTTP su questo endpoint rileva solo un processo morto. Il corpo JSON descrive lo stato attuale:
{
"status": "ok",
"runner_id": "ccrunner_...",
"active_sessions": 2,
"last_poll_at": "2026-03-31T18:04:11.220Z",
"last_poll_age_ms": 842
}
Usa last_poll_age_ms come segnale di vivacità nei probe personalizzati; un valore che cresce senza limiti indica che il ciclo di polling è bloccato. Sia last_poll_at che last_poll_age_ms sono null fino al completamento del primo polling.
L'orchestrator serve il suo /healthz sulla sua porta di salute. Il suo endpoint restituisce sempre 200, e il corpo porta un campo connected che segnala se il polling più recente ha avuto successo, più i conteggi della coda di spawn per stato in queue_counts. Gated readiness e alerting su connected piuttosto che sul codice di stato.
Quando il connettore SCM è configurato, il corpo /healthz dell'orchestrator porta anche scm_connector_connected e un oggetto scm_connector con connected, last_connected_at, last_error, reconnects e requests_forwarded. Entrambi i campi sono null quando --scm-connector-host non è impostato.
Metriche Prometheus
Ogni runner serve metriche Prometheus su GET /metrics sulla stessa porta di /healthz. Serie chiave:
| Series | Notes |
|---|---|
claude_code_self_hosted_runner_info{runner_id,version,client_label} |
Sempre 1; utile per l'inventario della flotta e il rilevamento della deriva di versione |
claude_code_self_hosted_runner_capacity |
--capacity configurato |
claude_code_self_hosted_runner_active_sessions |
Sessioni attualmente in esecuzione |
claude_code_self_hosted_runner_locked_account{email} |
Presente una volta che il runner si è bloccato a un utente e un token di sessione che porta un'affermazione act.email è stato emesso. La serie è assente su un runner bloccato a un agente Claude Tag, i cui token di sessione non portano act.email. Il valore dell'etichetta è l'email dell'account; se il tuo archivio di metriche è ampiamente leggibile, elimina o hash l'etichetta al momento della raschiatura, ad esempio con Prometheus metric_relabel_configs. |
claude_code_self_hosted_runner_last_poll_age_seconds |
Secondi dall'ultimo polling riuscito. Avviso se superiore a 60. |
claude_code_self_hosted_runner_poll_errors_total{error_kind} |
Errori cumulativi di PollWork per tipo: transport, timeout, 5xx, 429 o 4xx. Tutte e cinque le serie sono presenti dall'avvio del processo; avviso su rate(...[5m]) > 0. |
claude_code_self_hosted_runner_sessions_started_total{client_platform} |
Processi figlio della sessione generati durante la vita del runner, una serie per origine della sessione come web_claude_ai, ios, android, desktop_app o claude_code_cli, o unknown quando il server non ne ha inviato uno. Le sessioni Slack portano claude_in_slack o claude-in-slack a seconda di quale integrazione Slack le ha create, quindi abbina entrambe con un selettore regex come {client_platform=~"claude[-_]in[-_]slack"}. Usa sum() per il totale della flotta. |
claude_code_self_hosted_runner_sessions_completed_total{client_platform} |
Sessioni che sono terminate correttamente, etichettate allo stesso modo. Più ampio di una semplice uscita pulita: vedi session lifecycle counter semantics per cosa conta. |
claude_code_self_hosted_runner_sessions_failed_total{client_platform} |
Sessioni che sono terminate in errore, etichettate allo stesso modo. Stessa avvertenza: vedi session lifecycle counter semantics. |
claude_code_self_hosted_runner_sessions_interrupted_total{client_platform} |
Sessioni che il runner ha terminato per un motivo operativo piuttosto che un risultato di sessione, etichettate allo stesso modo. Vedi session lifecycle counter semantics. |
claude_code_self_hosted_runner_initializing_sessions |
Sessioni attualmente nella fase di init, dall'assegnazione all'evento di init del figlio |
claude_code_self_hosted_runner_session_init_duration_seconds |
Istogramma delle durate di init della sessione |
claude_code_self_hosted_runner_session_init_errors_total |
Sessioni che hanno fallito prima di raggiungere init: un errore di hook di checkout, preparazione git, problema di token o un crash pre-init del figlio |
claude_code_self_hosted_runner_session_start_hook_errors_total |
Hook SessionStart che hanno segnalato un risultato di errore, uno per esecuzione di hook fallita |
claude_code_self_hosted_runner_session_idle_seconds{session_id,client_platform} |
Gauge per sessione di secondi dall'inattività della sessione. Utile per terminare le sessioni bloccate su un prompt di autorizzazione senza risposta. |
L'orchestrator serve le sue serie su GET /metrics sulla stessa porta del suo /healthz:
| Series | Notes |
|---|---|
claude_code_self_hosted_orchestrator_info{version,pool_id,orchestrator_uuid,hostname} |
Sempre 1 |
claude_code_self_hosted_orchestrator_connected |
1 quando il polling più recente ha avuto successo; scende a 0 dopo qualsiasi polling fallito, qualunque sia il tipo di errore |
claude_code_self_hosted_orchestrator_last_poll_age_seconds |
Secondi dall'ultimo tentativo di polling, successo o errore, a differenza della metrica identicamente denominata del runner, che misura dall'ultimo successo; abbina con connected per catturare i polling falliti. Il ciclo di polling dell'orchestrator attende l'esecuzione dell'hook, quindi avviso sopra --hook-timeout più un margine, circa 90 secondi ai valori predefiniti, piuttosto che un flat 60. |
claude_code_self_hosted_orchestrator_poll_errors_total{error_kind} |
Errori cumulativi di PollSpawnHints per tipo: transport, timeout, 5xx, 429 o 4xx. Tutte e cinque le serie sono presenti dall'avvio del processo; avviso su rate(...[5m]) > 0. |
claude_code_self_hosted_orchestrator_queue_pending_sessions |
Richieste di spawn rivendicabili in questo momento |
claude_code_self_hosted_orchestrator_queue_backing_off_sessions |
Richieste di spawn in backoff di retry dopo un errore di hook riprova |
claude_code_self_hosted_orchestrator_queue_circuit_broken_sessions |
Richieste di spawn bloccate fino a quando un Owner non le riprova dalla scheda Activity dell'ambiente; avviso se superiore a zero |
claude_code_self_hosted_orchestrator_pool_pending_sessions |
Sessioni totali in attesa di un runner per questo ambiente. Aggregato a livello di ambiente, identico su ogni istanza dell'orchestrator: usa MAX piuttosto che SUM tra le istanze. |
claude_code_self_hosted_orchestrator_pool_active_sessions |
Sessioni attualmente assegnate a un runner vivo in questo ambiente. Aggregato a livello di ambiente, identico su ogni istanza dell'orchestrator: usa MAX piuttosto che SUM tra le istanze. |
claude_code_self_hosted_orchestrator_spawn_hooks_total{result} |
Risultati cumulativi dell'hook spawn-runner: ok, retryable, non_retryable. Conta le invocazioni dell'hook dell'orchestrator, non i figli della sessione che i runner generano: non comparabili a sessions_started_total, poiché la capacità superiore a uno, i pool caldi e i runner generati di nuovo per la stessa sessione divergono i due. |
claude_code_self_hosted_orchestrator_spawn_hook_duration_seconds |
Istogramma delle durate dell'hook |
claude_code_self_hosted_orchestrator_warm_hints_dispatched_total |
Richieste di spawn di standby inviate dall'avvio del processo |
claude_code_self_hosted_orchestrator_session_queue_wait_seconds |
Istogramma di secondi che ogni sessione ha atteso nella coda prima che l'orchestrator la rivendicasse per spawn, registrato dal timestamp di attesa della coda che il piano di controllo invia con la richiesta di spawn di ogni sessione. Usa per l'avviso del tempo di coda p50/p99. I spawn di pre-riscaldamento non vengono campionati. |
claude_code_self_hosted_orchestrator_clock_skew_seconds |
Skew dell'orologio locale meno server; diagnostico, presente una volta misurato |
claude_code_self_hosted_orchestrator_scm_connector_connected |
1 quando il WebSocket del connettore SCM è aperto; 0 durante la composizione o il backoff. Assente quando --scm-connector-host non è impostato. |
claude_code_self_hosted_orchestrator_scm_connector_requests_forwarded_total |
Richieste HTTP cumulative inoltrate all'host SCM configurato dall'avvio del processo. Assente quando --scm-connector-host non è impostato. |
Per l'autoscaling, scegli la serie che corrisponde al tuo stile di scaling e gated prima che si nutra nello scaler:
- Scaling della profondità della coda: alimenta
claude_code_self_hosted_orchestrator_pool_pending_sessionsnel tuo HPA o scaler KEDA, nonqueue_pending_sessions. - Scaling della capacità: scala sul rapporto tra
active_sessionsecapacitydel runner. - Gate su
connected: filtra la query conclaude_code_self_hosted_orchestrator_connected == 1per istanza, quindi il valore stantio di una replica disconnessa non si nutre nello scaler.
Durante un'interruzione completa del polling, ogni replica disconnessa, la query gated non restituisce dati. HPA mantiene il numero di replica attuale su una metrica mancante, ma lo scaler Prometheus di KEDA al suo ignoreNullValues: "true" predefinito legge il risultato vuoto come zero e scala in; imposta ignoreNullValues: "false" su ScaledObject, facoltativamente con un floor di replica fallback.
Il seguente PodMonitor di Prometheus Operator copre entrambi i processi. Seleziona i pod per l'etichetta app.kubernetes.io/part-of: claude-code-self-hosted-runner e la porta denominata health che la ricetta Kubernetes imposta; regola gli spazi dei nomi per corrispondere alla tua distribuzione:
# 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
Queste regole di avviso di esempio sono un punto di partenza; sintonizza le soglie per la dimensione della tua flotta:
# 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: increase(claude_code_self_hosted_runner_session_init_errors_total[10m]) > 3
for: 5m
labels: {severity: warning}
annotations:
summary: "Runner {{ $labels.pod }}: >3 session init failures in 10m (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: increase(claude_code_self_hosted_runner_session_start_hook_errors_total[10m]) > 3
for: 5m
labels: {severity: warning}
annotations:
summary: "Runner {{ $labels.pod }}: >3 SessionStart hook failures in 10m"
- 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: claude_code_self_hosted_orchestrator_queue_circuit_broken_sessions > 0
for: 1m
labels: {severity: critical}
annotations:
summary: "{{ $value }} sessions circuit-broken — spawn-runner hook is repeatedly non-retryable; fix infra then retry from the Activity tab"
- 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"
Passa attraverso le metriche del figlio della sessione
Ogni sessione viene eseguita nel suo processo figlio con le sue metriche OpenTelemetry; a --capacity superiore a uno, il runner riscrive come quelle metriche figlio vengono esposte. L'impostazione di OTEL_METRICS_EXPORTER=prometheus sull'host del runner e CLAUDE_CODE_ENABLE_TELEMETRY=1 nell'ambiente della sessione, ad esempio dal tuo script wrapper o dall'ambiente del runner stesso, che le sessioni ereditano, ri-espone gli strumenti di contatore e gauge di ogni figlio sull'endpoint /metrics del runner, insieme alle serie del runner. Il runner riscrive l'esportatore del figlio per eseguire il push su OTLP a un ricevitore solo loopback sulla porta di salute, etichetta ogni serie con etichette session_id e client_platform, e rimuove le serie di una sessione quando quella sessione termina. Gli istogrammi non passano, e una metrica figlio il cui nome entrerebbe in collisione con il prefisso del runner è eliminata.
Al --capacity 1 predefinito, la riscrittura non si applica: il figlio della sessione lega il suo endpoint Prometheus sulla porta 9464 come al solito.
Semantica del contatore del ciclo di vita della sessione
I contatori sessions_started_total, sessions_completed_total, sessions_failed_total e sessions_interrupted_total classificano ogni sessione in base a come è terminata. Ogni figlio della sessione generato incrementa sessions_started_total al momento della generazione, e esattamente uno degli altri tre incrementa all'uscita, quindi sessions_started_total meno la somma degli altri tre è uguale al numero di figli della sessione attualmente in esecuzione.
completed: la sessione è terminata correttamente. Questo copre il figlio che esce da solo con codice0, la sessione archiviata o eliminata mentre il figlio era ancora connesso, e il runner che restituisce lo slot in modo pulito: il rilascio della sessione al timeout di inattività, al tempo di ritiro o al limite--kill-session-after-min; un timeout di avvio; o un deassign lato server che il ciclo di polling ha notato prima che il figlio uscisse. Incrementasessions_completed_total.failed: il figlio è uscito da solo con un codice diverso da zero, sia un crash che un errore di configurazione dopo la generazione. Incrementasessions_failed_total.interrupted: il runner ha terminato il figlio per un motivo operativo che non è né un successo della sessione né un errore del runner, come un drenaggio, o terminando una sessione che era ancora sul runner quando la finestra di graziaSELF_HOSTED_RUNNER_MAX_LIFETIME_GRACE_MSdopo il suo limite--kill-session-after-minè terminata. Un riavvio rolling di Kubernetes che inviaSIGTERMè un esempio di drenaggio. Incrementasessions_interrupted_total.
Prima della v2.1.260, il runner terminava ogni sessione che raggiungeva il suo limite --kill-session-after-min e la contava in sessions_interrupted_total.
Il CLAUDE_RUNNER_EXIT_REASON dell'hook post-session classifica gli handoff puliti diversamente. L'hook segnala un rilascio, un timeout di avvio e un deassign del server come interrupted, perché il runner ha fermato il figlio. Questi contatori registrano gli stessi eventi come completed, perché lo slot è stato restituito correttamente.
Se riconcili le ricevute dell'hook direttamente contro sessions_completed_total, sottostimi i completamenti. Usa l'hook per le garanzie per sessione e i contatori per i tassi aggregati.
Su un ambiente monouso, --capacity 1 con il --drain-grace-sec 0 predefinito, ogni processo del runner esce momenti dopo la fine della sua sessione. sessions_completed_total, sessions_failed_total e sessions_interrupted_total incrementano solo alla fine della sessione, subito prima di quell'uscita, quindi un raschiamento Prometheus ogni 15-60 secondi raramente cattura l'incremento prima che le serie del runner scompaiano; questi tre contatori di fine sessione sono i contatori terminali a cui il resto di questa sezione si riferisce. sessions_started_total incrementa alla generazione e rimane visibile per la vita della sessione, quindi si mostra in modo affidabile, ma su un ambiente monouso legge più vicino a "sessioni attualmente in esecuzione" che a un conteggio cumulativo.
Usa la serie in questa tabella per l'obiettivo corrispondente invece dei contatori terminali:
| Goal | Use |
|---|---|
| Throughput | claude_code_self_hosted_orchestrator_spawn_hooks_total{result="ok"}, un contatore sull'orchestrator di lunga durata che incrementa una volta per hook spawn-runner riuscito e rimane significativo sotto rate(). Conta le invocazioni dell'hook piuttosto che le sessioni, quindi il pre-riscaldamento e i spawn ripetuti per la stessa sessione divergono da conteggi di sessione. |
| Utilization | sum(claude_code_self_hosted_runner_active_sessions) contro sum(claude_code_self_hosted_runner_capacity), entrambi i gauge validi ad ogni raschiamento indipendentemente dalla durata del runner |
| Backlog | claude_code_self_hosted_orchestrator_pool_pending_sessions per la profondità della coda, e claude_code_self_hosted_orchestrator_queue_circuit_broken_sessions, avviso se superiore a zero |
| Failures | claude_code_self_hosted_runner_sessions_failed_total, best effort: i veri crash dopo la generazione incrementano, e rate() è significativo su runner che sopravvivono alle loro sessioni con --drain-grace-sec superiore a 0. Un ambiente monouso ha lo stesso problema della finestra di raschiamento degli altri contatori terminali, quindi tratta qualsiasi valore diverso da zero che vedi come degno di indagine. I fallimenti prima della generazione, come un errore di hook di checkout, preparazione git o un problema di token, appaiono solo in session_init_errors_total. |
Le righe orchestrator_* esistono solo su ambienti che eseguono l'orchestrator on-demand. Su una flotta fissa i cui runner sopravvivono alle loro sessioni, con --drain-grace-sec superiore a 0, usa sum(rate(claude_code_self_hosted_runner_sessions_started_total[5m])) per il throughput; su una flotta monouso quella serie ha lo stesso problema della finestra di raschiamento dei contatori terminali, quindi affidati al conteggio delle sessioni in coda. Controlla il backlog nella scheda Activity dell'ambiente, nella pagina di amministrazione Cloud environments: i runner non esportano una serie di profondità della coda.
Per la segnalazione dei risultati per sessione, usa l'hook post-session invece: si attiva alla fine di ogni sessione dove un processo figlio è stato generato, a parte la terminazione abrupte del runner come una preemption VM, per il contratto proprio dell'hook.
Prossimi passi
- Self-hosted environments: l'ambiente, il runner e il modello di sessione; la guida rapida e Deploy to production contengono la configurazione e le operazioni
- Customize sessions: script wrapper, hook del ciclo di vita e runner on-demand
- Verify session identity: il token di sessione, le sue affermazioni e come verificarlo