SpyBara
Go Premium

self-hosted-environments-reference.md 2026-09-11 23:01 UTC to 2026-09-12 03:02 UTC

This page contains 338 additions and 0 deletions.

2026
Sat 12 03:02 Fri 18 23:58 Sat 19 23:57

Référence des environnements auto-hébergés

Référence complète pour le runner et l'orchestrateur auto-hébergés : drapeaux CLI, variables d'environnement et métriques Prometheus.

Cette page est la référence pour les deux processus que vous exécutez dans un environnement auto-hébergé : le runner, qui exécute les sessions cloud Claude Code sur vos hôtes, et l'orchestrateur d'autoscaling optionnel, qui démarre les runners à mesure que les sessions s'accumulent. Chacun a sa propre table de drapeaux. Les deux s'exécutent sur des hôtes Linux ou macOS, pour lesquels les valeurs par défaut telles que /workspace et ~/.claude s'appliquent. Exécutez claude self-hosted-runner --help pour la liste faisant autorité sur votre version installée.

Les séries de métriques et quelques champs API utilisent toujours pool pour ce que ces pages appellent un environnement ; les deux termes désignent la même chose. L'ID d'environnement est le champ pool_id, avec la forme ccpool_... : partout où ces pages affichent un identifiant pool, il désigne l'environnement. Les drapeaux CLI et les variables d'environnement l'écrivent environment, comme --environment-secret-file ; les orthographes pool dépréciées fonctionnent toujours, comme la ligne --environment-secret-file le décrit.

Drapeaux CLI du runner

La plupart des drapeaux ont une variable d'environnement correspondante. Quand les deux sont définis, le drapeau a la priorité. Les drapeaux de durée prennent des minutes ou des secondes sur la CLI, mais la variable d'environnement appariée est toujours en millisecondes, indiquée par le suffixe _MS, et la colonne Par défaut affiche l'unité du drapeau : --exit-if-unused-min 10 équivaut à SELF_HOSTED_RUNNER_IDLE_SHUTDOWN_MS=600000, et une valeur Helm comme SELF_HOSTED_RUNNER_STARTUP_TIMEOUT_MS: "15" signifie 15 millisecondes, pas la valeur par défaut de 15 minutes.

Drapeau Variable d'env Par défaut Description
--api-url <url> aucune https://api.anthropic.com URL de base de l'API. À remplacer uniquement pour les tests.
--base-dir <path> SELF_HOSTED_RUNNER_BASE_DIR /workspace ; aucune sur Windows Répertoire pour les clones de dépôts et les répertoires de travail par session. Le runner a besoin d'un accès en écriture à ce chemin ou à son parent. Le runner crée le répertoire au démarrage et se termine avec cannot create or write to base directory quand il ne peut pas le créer ou y écrire. Avant v2.1.225, le runner créait le répertoire au démarrage de la première session, donc un chemin inutilisable échouait les sessions plutôt que le démarrage. Sur Windows, qui n'est pas un hôte runner supporté, il n'y a pas de valeur par défaut : le runner se termine au démarrage sauf si vous passez le drapeau ou définissez la variable. Utilisez la même valeur sur chaque runner dans un environnement. Voir Garder le répertoire de base et la capacité identiques sur tous les runners.
--capacity <n> aucune 1 Nombre maximum de sessions simultanées que ce runner gère. Toutes les sessions appartiennent au même propriétaire verrouillé. Utilisez la même valeur sur chaque runner dans un environnement ; voir Garder le répertoire de base et la capacité identiques sur tous les runners.
--client-label <label> SELF_HOSTED_RUNNER_CLIENT_LABEL le nom d'hôte de l'hôte Étiquette que le runner envoie lors de son enregistrement. Le runner la signale également comme l'étiquette client_label de claude_code_self_hosted_runner_info. Nécessite Claude Code v2.1.248 ou ultérieur.
--configure-git SELF_HOSTED_RUNNER_CONFIGURE_GIT=1 désactivé Écrire l'identité git globale et activer la signature de commit Anthropic au démarrage. Voir Configurer git.
--confine-repo-settings <mode> SELF_HOSTED_RUNNER_CONFINE_REPO_SETTINGS warn Définit le mode de la garde qui signale une session quand les paramètres validés d'un dépôt tentent d'accorder un accès en écriture ou en lecture en dehors de l'espace de travail de cette session, de définir des variables d'environnement ou de remplacer la posture sandbox ou hooks de l'opérateur, comme sandbox.enabled: false ou disableAllHooks. Le warn par défaut enregistre la violation et démarre quand même la session, enforce refuse la session, et off désactive l'analyse. Voir Renforcer votre déploiement.
--debug-token-dir <path> SELF_HOSTED_RUNNER_DEBUG_TOKEN_DIR non défini Écrire les tokens en direct sur le disque pour inspection. Débogage uniquement ; ne pas utiliser en production.
--defer-shutdown-max-min <n> SELF_HOSTED_RUNNER_DEFER_SHUTDOWN_MAX_MS 0 Au premier SIGTERM ou SIGINT, continuer à servir les sessions déjà attachées au lieu de les drainer, puis libérer tout ce qui est encore attaché N minutes plus tard et quitter. Augmentez le délai d'arrêt de votre hôte avant de définir ceci. Voir Différer le drainage après le premier signal. 0 désactive. Nécessite Claude Code v2.1.238 ou ultérieur.
--drain-grace-sec <n> SELF_HOSTED_RUNNER_DRAIN_GRACE_MS 0 Jusqu'à ce que le runner reçoive un signal d'arrêt ou atteigne son heure de retraite, contrôle quand le runner se termine après la fin de ses sessions actives : 0 se termine immédiatement sans interrogation supplémentaire, et une valeur positive garde le runner actif et réinterroge la file d'attente du propriétaire verrouillé pendant ce nombre de secondes d'abord, au prix de l'isolation de conteneur par session décrite dans la section de renforcement. Après un premier signal que vous avez différé avec --defer-shutdown-max-min, le runner se termine dès qu'il ne détient aucune session, quelle que soit la valeur que vous définissez ici.
--drain-wait-sec <n> SELF_HOSTED_RUNNER_DRAIN_WAIT_MS 0 Une fois le drainage commencé, qui se fait sur SIGTERM sauf si vous définissez --defer-shutdown-max-min, attendez jusqu'à N secondes pour que le tour en vol de chaque session et les tâches de fond se terminent avant de terminer l'enfant. Pendant cette attente, le runner compte une tâche de fond qui vient de se terminer comme toujours en cours d'exécution jusqu'au tour de suivi qui lit son résultat commence, pendant au maximum la fenêtre SELF_HOSTED_RUNNER_BG_RESULT_GRACE_MS.
--environment-secret-file <path> SELF_HOSTED_RUNNER_ENVIRONMENT_SECRET requis Chemin vers un fichier contenant le secret d'environnement, ou, pour les runners générés par l'orchestrateur, le JWT de bon de travail à usage unique. SELF_HOSTED_RUNNER_ENVIRONMENT_SECRET porte la valeur secrète directement, pas un chemin de fichier. L'ancien drapeau --pool-secret-file et la variable SELF_HOSTED_RUNNER_POOL_SECRET fonctionnent toujours et impriment un avis de dépréciation sur stderr ; les builds de runner du programme d'aperçu plus anciens que 2.1.216 ne reconnaissent que ces anciens noms.
--exec-path <path> SELF_HOSTED_RUNNER_EXEC_PATH binaire propre Binaire ou script wrapper à générer pour chaque session. Voir Scripts wrapper.
--exit-if-unused-min <n> SELF_HOSTED_RUNNER_IDLE_SHUTDOWN_MS 0 Quitter après N minutes d'interrogation sans travail jamais assigné, pour la réduction d'échelle de l'autoscaler. 0 désactive.
--git-host-rewrite <from>=<to> aucune non défini Réécrire les URL sources https://<from>/... en https://<to>/... avant le clonage, pour DNS à horizon divisé. Répétable ; drapeau uniquement.
--git-ssh-rewrite <host> aucune non défini Réécrire les URL sources https://<host>/... en git@<host>:... avant le clonage, pour les hôtes git SSH uniquement. Répétable ; drapeau uniquement.
--health-port <port> SELF_HOSTED_RUNNER_HEALTH_PORT 8080 Port pour l'écouteur /healthz et /metrics. Définir 0 pour désactiver.
--hooks-dir <path> SELF_HOSTED_RUNNER_HOOKS_DIR non défini Répertoire des scripts de hook de cycle de vie. Voir Hooks de cycle de vie.
--kill-session-after-min <n> SELF_HOSTED_RUNNER_MAX_LIFETIME_MS 0 Terminer un enfant de session une fois qu'il a vécu N minutes en temps réel, comme limite de sécurité pour les sessions bloquées. Le runner termine l'arborescence des processus de la session, y compris toutes les commandes que la session a laissées en cours d'exécution. Le runner diffère une suppression qui tombe au milieu d'un tour jusqu'à la fin du tour, pendant au maximum la fenêtre SELF_HOSTED_RUNNER_MAX_LIFETIME_GRACE_MS. Pour choisir une valeur, voir Certaines sessions ne comptent pas comme inactives. 0 désactive.
--lock-to-account <id> SELF_HOSTED_RUNNER_LOCK_TO_ACCOUNT non défini Pré-verrouiller le runner à un compte spécifique au démarrage au lieu de verrouiller à la première session. Accepte une adresse e-mail ou un ID user_... dans l'organisation de l'environnement. Un runner pré-verrouillé ne récupère jamais les sessions du canal Claude Tag, qui n'ont pas de compte.
--log-file <path> SELF_HOSTED_RUNNER_LOG_FILE non défini Refléter les logs du runner vers un fichier en plus de stdout et stderr, créé avec les permissions 0600. Requis pour que self-hosted-runner doctor suive les logs localement.
--log-level <level> aucune info info ou debug
--post-session-hook-timeout-sec <n> SELF_HOSTED_RUNNER_POST_SESSION_HOOK_TIMEOUT_MS 60 Budget pour le hook post-session à la fin de chaque session, y compris l'arrêt du runner
--proxy-authorization-command <command> SELF_HOSTED_RUNNER_PROXY_AUTHORIZATION_COMMAND non défini Commande shell que le runner exécute pour chaque connexion à votre proxy de sortie, en utilisant sa stdout coupée comme valeur d'en-tête Proxy-Authorization. Nécessite HTTPS_PROXY ou HTTP_PROXY, et ne peut pas être combiné avec --proxy-authorization-file. Voir S'authentifier auprès d'un proxy de sortie. Nécessite Claude Code v2.1.238 ou ultérieur.
--proxy-authorization-file <path> SELF_HOSTED_RUNNER_PROXY_AUTHORIZATION_FILE non défini Fichier que le runner lit pour chaque connexion à votre proxy de sortie, en utilisant son contenu coupé comme valeur d'en-tête Proxy-Authorization. Utilisez ce drapeau pour un token qu'un autre processus fait tourner en place. Porte les mêmes exigences que --proxy-authorization-command, et ne peut pas être combiné avec lui. Voir S'authentifier auprès d'un proxy de sortie. Nécessite Claude Code v2.1.238 ou ultérieur.
--push-outcome-on-release SELF_HOSTED_RUNNER_PUSH_OUTCOME_ON_RELEASE désactivé À la fin d'une session initiée par le runner comme un drainage ou une libération inactive, pousser les branches de résultat suivies vers origin avant de supprimer l'espace de travail, afin que les commits en vol survivent à un redémarrage. Meilleur effort ; ajoute 30 secondes au budget d'arrêt, et nécessite git 2.29 ou plus récent pour reprendre à partir de la branche poussée. Restreindre l'accès en push aux refs claude/* avant d'activer ; voir Les sessions reprises perdent le travail non poussé. Les dépôts extraits via un hook de cycle de vie checkout ne sont pas poussés ; prenez des snapshots de ceux-ci à partir du hook post-session à la place.
--release-idle-session-min <n> SELF_HOSTED_RUNNER_SESSION_IDLE_MS 0 Libérer un créneau de session après N minutes d'inactivité une fois qu'un tour se termine ou que la session attend l'action de l'utilisateur. Une session qui est toujours au milieu d'un tour, y compris une qui détient une tâche de fond qui ne finit jamais ou une approbation demandée de l'intérieur d'un appel d'outil en cours d'exécution, ne compte pas comme inactive ; associer avec --kill-session-after-min comme butée dure. Après la fin de la tâche de fond d'une session, le runner considère la session comme occupée jusqu'au tour de suivi qui lit le résultat commence, pendant au maximum la fenêtre SELF_HOSTED_RUNNER_BG_RESULT_GRACE_MS. Jusqu'à ce que le runner reçoive un signal d'arrêt ou atteigne son heure de retraite, une libération qui laisse le runner sans sessions actives démarre le même chemin de sortie qu'un drainage normal, gouverné par --drain-grace-sec. Après un premier signal que vous avez différé avec --defer-shutdown-max-min, le runner se termine dès qu'une libération le laisse sans sessions. 0 désactive.
--retire-at <epoch-seconds> SELF_HOSTED_RUNNER_RETIRE_AT non défini Retirer le runner à un timestamp Unix absolu en secondes, pour l'infrastructure qui tue le runner à un moment connu ; Cycle de vie du runner décrit la séquence de libération et comment dimensionner la marge. Les valeurs avant 2001 ou après l'année 5138 sont rejetées par le drapeau et ignorées par la variable d'environnement.
--session-stop-grace-sec <n> SELF_HOSTED_RUNNER_SESSION_STOP_GRACE_MS 5 Combien de temps attendre que le processus Claude se termine proprement après la fin d'une session, avant de le tuer de force. Augmentez la valeur si les hooks SessionEnd propres de l'enfant ont besoin de plus de temps.
--startup-timeout-min <n> SELF_HOSTED_RUNNER_STARTUP_TIMEOUT_MS 15 Libérer un créneau de session si l'enfant n'a pas signalé qu'il s'était initialisé dans N minutes après le lancement. Effacé par le signal d'init de l'enfant sur le canal d'activité, pas par la sortie ordinaire, après quoi --release-idle-session-min prend le relais. 0 désactive.
--trust-workspace [bool] SELF_HOSTED_RUNNER_TRUST_WORKSPACE activé Amorcer la confiance persistante pour les chemins de dépôt de chaque session afin que les permissions.allow et additionalDirectories validés par le dépôt soient honorés. Définir false pour supprimer les subventions de permission validées par le dépôt et configurer les règles d'autorisation dans le settings.json de la configuration d'hôte à la place ; les paramètres sandbox.* validés par le dépôt s'appliquent toujours de toute façon, c'est pourquoi la garde de paramètres de dépôt les analyse indépendamment de ce drapeau.
--use-anthropic-git-proxy CLAUDE_RUNNER_USE_GIT_PROXY=1 désactivé Cloner via le proxy git d'Anthropic au lieu de l'authentification git gérée par le client. Nécessite --capacity 1 et git 2.32 ou plus récent ; le runner refuse de démarrer sinon. Remplace les drapeaux de réécriture.

La plupart des drapeaux de durée ont un maximum, choisi pour garder chaque délai d'attente en dessous du plafond de minuteur 32 bits du runtime d'environ 24,85 jours. Les drapeaux --*-min sont plafonnés à 10080 minutes, 7 jours ; --drain-grace-sec à 604800 secondes, également 7 jours ; et --drain-wait-sec à 86400 secondes, 24 heures. --session-stop-grace-sec et --post-session-hook-timeout-sec ne sont pas plafonnés. Dépasser un plafond se comporte différemment par surface :

  • Drapeau : le démarrage échoue avec une erreur.
  • Variable d'environnement : le runner serre la valeur au plafond de minuteur plutôt que de la rejeter.

Drapeaux CLI de l'orchestrateur

La sous-commande self-hosted-runner orchestrator, qui génère les runners à la demande, accepte --api-url, --environment-secret-file, --hooks-dir, --health-port et --log-level avec les mêmes valeurs par défaut que le runner et, où le drapeau du runner en a une, la même variable d'environnement, sauf que --hooks-dir est requis et doit contenir un hook spawn-runner. Il prend également ses propres drapeaux :

Drapeau Par défaut Description
--hook-concurrency <n> 4 Nombre maximum de hooks spawn-runner s'exécutant en parallèle. Limite également le nombre de demandes de génération réclamées par interrogation.
--hook-timeout <sec> 60 Terminer l'arborescence des processus du hook après ce nombre de secondes. Le délai d'attente plus sa grâce de suppression de 5 secondes doit rester en dessous de --expected-spawn-seconds ; l'orchestrateur applique ceci au démarrage.
--expected-spawn-seconds <sec> 120 Temps de démarrage p99 attendu pour les runners générés, dans la plage appliquée par le serveur 10 à 3600. Envoyé à chaque interrogation comme le bail côté serveur ; si aucun runner ne s'enregistre avant son expiration, la session est re-proposée avec un nouvel ID de commande. Tous les réplicas doivent partager cette valeur.
--min-idle <n> 0 Garder au moins N créneaux de session inactifs libres en générant proactivement des runners de secours. 0 désactive le préchauffage. Associer avec le --exit-if-unused-min du runner afin que les runners de secours excédentaires se réclament eux-mêmes.
--debug-dir <path> non défini Écrire le bon de travail de chaque demande de génération et la stderr du hook sur le disque. Débogage uniquement ; ne jamais définir en production.

Drapeaux du connecteur SCM

L'orchestrateur peut maintenir une connexion WebSocket permanente au plan de contrôle d'Anthropic afin que les flux pré-session hébergés, comme le sélecteur de dépôt et le résolveur de branche ou de ref, puissent atteindre un hôte GitHub Enterprise Server qui n'est routable que de l'intérieur de votre réseau. Le connecteur reste désactivé sauf si vous définissez --scm-connector-host.

Drapeau Par défaut Description
--scm-connector-host <host[:port]> non défini Nom d'hôte GitHub Enterprise Server vers lequel transférer les demandes. Le port par défaut est 443. Définir ce drapeau active le connecteur.
--scm-connector-id <n> requis avec --scm-connector-host L'ID numérique de la connexion GitHub Enterprise Server de votre organisation. Contactez votre équipe de compte Anthropic pour la valeur quand vous activez le connecteur.
--scm-connector-provider <slug> ghe Segment de chemin identifiant le fournisseur, correspondant à ^[a-z0-9-]{1,32}$.
--scm-connector-ca-file <path> non défini Bundle CA supplémentaire, au format PEM, pour les connexions TLS à l'hôte GitHub Enterprise Server.
--scm-connector-host-rewrite <from>=<to_host:to_port> non défini Pour les tests de bout en bout uniquement : redirige la connexion TCP tout en gardant l'en-tête Host et TLS SNI comme --scm-connector-host.

Le connecteur s'authentifie avec le secret d'environnement existant de l'orchestrateur et se reconnecte automatiquement : avec backoff exponentiel sur une connexion abandonnée, ou un délai fixe de 30 secondes quand le plan de contrôle ferme la connexion parce qu'un autre réplica d'orchestrateur la détient déjà.

Paramètres réservés aux variables d'environnement

Ces paramètres du runner sont lus uniquement à partir de l'environnement et couvrent le comportement que la plupart des déploiements laissent à la valeur par défaut :

Variable d'env Par défaut Description
SELF_HOSTED_RUNNER_BG_RESULT_GRACE_MS 30000 Combien de temps le runner considère une session comme occupée après la fin d'une tâche de fond tandis que le tour de suivi qui lit le résultat n'a pas commencé. Les lignes --drain-wait-sec et --release-idle-session-min décrivent où la retenue s'applique au drainage et à la libération inactive, et Cycle de vie du runner décrit où elle s'applique à la retraite --retire-at. 0 ou une valeur inutilisable revient à la valeur par défaut, donc la retenue ne peut pas être désactivée. Nécessite Claude Code v2.1.228 ou ultérieur.
SELF_HOSTED_RUNNER_HOST_CONFIG_DIR ~/.claude Répertoire capturé dans le snapshot de démarrage du runner et amorcé dans le CLAUDE_CONFIG_DIR de chaque session ; les modifications sur le disque s'appliquent après un redémarrage du runner. Définir la variable déplace également l'endroit où le runner lit .claude.json pour l'amorçage MCP, donc le définir, y compris à sa propre valeur par défaut, relocalise cette recherche ; pointez vers un répertoire vide pour désactiver complètement l'amorçage.
SELF_HOSTED_RUNNER_MAX_LIFETIME_GRACE_MS 900000 Limite combien de temps une suppression --kill-session-after-min est différée en attendant la fin d'un tour en vol
SELF_HOSTED_RUNNER_SIGKILL_GRACE_MS 30000 Combien de temps le runner attend que le système d'exploitation livre SIGKILL à un enfant bloqué dans les E/S non interruptibles avant de se terminer lui-même. Plancher à --post-session-hook-timeout-sec plus 15 secondes, et 30 de plus quand --push-outcome-on-release est défini, donc le minimum effectif est 75 secondes aux valeurs par défaut.
CLAUDE_RUNNER_FETCH_DEPTH 50 Profondeur de récupération git pour les clones frais. Définir un entier positif, ou full ou 0 pour une récupération complète. Les dépôts déjà présents dans l'espace de travail conservent leur profondeur existante.
CLAUDE_RUNNER_SKIP_GIT_VERIFY non défini Quand 1, ignorer la vérification de présence .git après l'exécution d'un hook checkout. Définir ceci quand votre hook matérialise une source non-git.
FORCE_AUTOUPDATE_PLUGINS non défini Quand 1, laisser les marchés de plugins se mettre à jour automatiquement même si le binaire est épinglé
CLAUDE_CODE_DISABLE_ARTIFACT non défini Quand 1, désactiver l'outil Artifact dans les sessions indépendamment du paramètre d'administration de l'organisation, et supprimer l'exigence de sortie *.frame.claudeusercontent.com

Télémétrie

Les enfants de session envoient la télémétrie opérationnelle à Anthropic sauf si vous la désactivez. Aucun code ou contenu de dépôt n'est envoyé. Définir les variables de télémétrie sur le processus du runner ; le runner les réaffirme après l'application des variables d'environnement fournies par le serveur, donc le paramètre de l'opérateur a toujours la priorité.

Un contrôle est spécifique aux environnements auto-hébergés : CLAUDE_CODE_BYOC_ENABLE_DATADOG=1 opte pour les métriques opérationnelles Datadog, qui sont désactivées par défaut dans les environnements auto-hébergés. Les contrôles de télémétrie Claude Code généraux, DISABLE_TELEMETRY, DO_NOT_TRACK, DISABLE_ERROR_REPORTING et CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC, s'appliquent aux enfants de session comme documenté dans la référence des variables d'environnement. DISABLE_GROWTHBOOK est connexe mais différent : définir DISABLE_GROWTHBOOK=1 désactive la récupération des drapeaux de fonctionnalité, et la télémétrie reste activée sauf si DISABLE_TELEMETRY est également défini.

CLAUDE_CODE_ENABLE_TELEMETRY n'est pas connexe : il active l'export OpenTelemetry vers votre propre collecteur, comme décrit dans Surveillance, et ne contrôle pas l'analytique d'Anthropic.

Point de terminaison de santé

Le runner sert GET /healthz sur le port de santé configuré. La réponse est 200 OK chaque fois que le processus est actif, quel que soit l'état de la boucle d'interrogation, donc une sonde HTTP sur ce point de terminaison détecte uniquement un processus mort. Le corps JSON décrit l'état actuel :

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

Utilisez last_poll_age_ms comme signal de vivacité dans les sondes personnalisées ; une valeur qui croît sans limite indique que la boucle d'interrogation est bloquée. À la fois last_poll_at et last_poll_age_ms sont null jusqu'à la fin de la première interrogation.

L'orchestrateur sert son propre /healthz sur son port de santé. Son point de terminaison retourne toujours 200, et le corps porte un champ connected signalant si l'interrogation la plus récente a réussi, plus les comptes de file d'attente de génération par état dans queue_counts. Gater la disponibilité et les alertes sur connected plutôt que sur le code de statut.

Quand le connecteur SCM est configuré, le corps /healthz de l'orchestrateur porte également scm_connector_connected et un objet scm_connector avec connected, last_connected_at, last_error, reconnects et requests_forwarded. Les deux champs sont null quand --scm-connector-host n'est pas défini.

Métriques Prometheus

Chaque runner sert les métriques Prometheus à GET /metrics sur le même port que /healthz. Séries clés :

Série Notes
claude_code_self_hosted_runner_info{runner_id,version,client_label} Toujours 1 ; utile pour l'inventaire de flotte et la détection de dérive de version
claude_code_self_hosted_runner_capacity --capacity configuré
claude_code_self_hosted_runner_active_sessions Sessions actuellement en cours d'exécution
claude_code_self_hosted_runner_locked_account{email} Présent une fois que le runner s'est verrouillé à un utilisateur et qu'un token de session portant une revendication act.email a été émis. La série est absente sur un runner verrouillé à un agent Claude Tag, dont les tokens de session ne portent pas act.email. La valeur d'étiquette est l'e-mail du compte ; si votre magasin de métriques est largement lisible, supprimez ou hachez l'étiquette au moment de la récupération, par exemple avec les metric_relabel_configs Prometheus.
claude_code_self_hosted_runner_last_poll_age_seconds Secondes depuis la dernière interrogation réussie. Alerter si plus de 60.
claude_code_self_hosted_runner_poll_errors_total{error_kind} Cumul des défaillances PollWork par type : transport, timeout, 5xx, 429 ou 4xx. Les cinq séries sont présentes depuis le démarrage du processus ; alerter sur rate(...[5m]) > 0.
claude_code_self_hosted_runner_sessions_started_total{client_platform} Processus enfants de session générés au cours de la durée de vie du runner, une série par origine de session comme web_claude_ai, ios, android, desktop_app ou claude_code_cli, ou unknown quand le serveur n'en a pas envoyé. Les sessions Slack portent soit claude_in_slack soit claude-in-slack selon l'intégration Slack qui les a créées, donc correspondre aux deux avec un sélecteur regex comme {client_platform=~"claude[-_]in[-_]slack"}. Utiliser sum() pour le total de la flotte.
claude_code_self_hosted_runner_sessions_completed_total{client_platform} Sessions qui se sont terminées proprement, étiquetées de la même manière. Plus large qu'une simple sortie propre : voir sémantique du compteur de cycle de vie de session pour ce qui compte.
claude_code_self_hosted_runner_sessions_failed_total{client_platform} Sessions qui se sont terminées en échec, étiquetées de la même manière. Même mise en garde : voir sémantique du compteur de cycle de vie de session.
claude_code_self_hosted_runner_sessions_interrupted_total{client_platform} Sessions que le runner a terminées pour une raison opérationnelle plutôt qu'un résultat de session, étiquetées de la même manière. Voir sémantique du compteur de cycle de vie de session.
claude_code_self_hosted_runner_initializing_sessions Sessions actuellement en phase d'init, de l'assignation jusqu'à l'événement d'init de l'enfant
claude_code_self_hosted_runner_session_init_duration_seconds Histogramme des durées d'init de session
claude_code_self_hosted_runner_session_init_errors_total Sessions qui ont échoué avant d'atteindre l'init : une défaillance du hook checkout, la préparation git, un problème de token ou un crash d'enfant pré-init
claude_code_self_hosted_runner_session_start_hook_errors_total Hooks SessionStart qui ont signalé un résultat d'erreur, un par exécution de hook échouée
claude_code_self_hosted_runner_session_idle_seconds{session_id,client_platform} Jauge par session de secondes depuis que la session est devenue inactive. Utile pour terminer les sessions bloquées sur une invite de permission sans réponse.

L'orchestrateur sert ses propres séries à GET /metrics sur le même port que son /healthz :

Série Notes
claude_code_self_hosted_orchestrator_info{version,pool_id,orchestrator_uuid,hostname} Toujours 1
claude_code_self_hosted_orchestrator_connected 1 quand l'interrogation la plus récente a réussi ; tombe à 0 après toute interrogation échouée, quel que soit le type d'échec
claude_code_self_hosted_orchestrator_last_poll_age_seconds Secondes depuis la dernière tentative d'interrogation, succès ou échec, contrairement à la métrique identiquement nommée du runner, qui mesure depuis le dernier succès ; associer avec connected pour attraper les interrogations échouées. La boucle d'interrogation de l'orchestrateur attend l'exécution du hook, donc alerter au-dessus de --hook-timeout plus une marge, autour de 90 secondes aux valeurs par défaut, plutôt qu'un plat 60.
claude_code_self_hosted_orchestrator_poll_errors_total{error_kind} Cumul des défaillances PollSpawnHints par type : transport, timeout, 5xx, 429 ou 4xx. Les cinq séries sont présentes depuis le démarrage du processus ; alerter sur rate(...[5m]) > 0.
claude_code_self_hosted_orchestrator_queue_pending_sessions Demandes de génération réclamables en ce moment
claude_code_self_hosted_orchestrator_queue_backing_off_sessions Demandes de génération en backoff de nouvelle tentative après une défaillance de hook réessayable
claude_code_self_hosted_orchestrator_queue_circuit_broken_sessions Demandes de génération bloquées jusqu'à ce qu'un Propriétaire les réessaye à partir de l'onglet Activity de l'environnement ; alerter si au-dessus de zéro
claude_code_self_hosted_orchestrator_pool_pending_sessions Total des sessions attendant un runner pour cet environnement. Agrégat à l'échelle de l'environnement, identique sur chaque instance d'orchestrateur : utiliser MAX plutôt que SUM entre les instances.
claude_code_self_hosted_orchestrator_pool_active_sessions Sessions actuellement assignées à un runner actif dans cet environnement. Agrégat à l'échelle de l'environnement, identique sur chaque instance d'orchestrateur : utiliser MAX plutôt que SUM entre les instances.
claude_code_self_hosted_orchestrator_spawn_hooks_total{result} Cumul des résultats du hook spawn-runner : ok, retryable, non_retryable. Compte les invocations de hook d'orchestrateur, pas les enfants de session que les runners génèrent : non comparable à sessions_started_total, puisque la capacité au-dessus d'un, les pools chauds et les runners générés à nouveau pour la même session divergent les deux.
claude_code_self_hosted_orchestrator_spawn_hook_duration_seconds Histogramme des durées de hook
claude_code_self_hosted_orchestrator_warm_hints_dispatched_total Demandes de génération de secours expédiées depuis le démarrage du processus
claude_code_self_hosted_orchestrator_session_queue_wait_seconds Histogramme de secondes que chaque session a attendu dans la file d'attente avant que l'orchestrateur la réclame pour la génération, enregistré à partir de l'horodatage d'attente de file d'attente que le plan de contrôle envoie avec la demande de génération de chaque session. Utiliser pour les alertes de temps d'attente p50/p99. Les générations de préchauffage ne sont pas échantillonnées.
claude_code_self_hosted_orchestrator_clock_skew_seconds Décalage d'horloge local moins serveur ; diagnostic, présent une fois mesuré
claude_code_self_hosted_orchestrator_scm_connector_connected 1 quand le WebSocket du connecteur SCM est ouvert ; 0 lors de la composition ou du backoff. Absent quand --scm-connector-host n'est pas défini.
claude_code_self_hosted_orchestrator_scm_connector_requests_forwarded_total Cumul des requêtes HTTP proxifiées vers l'hôte SCM configuré depuis le démarrage du processus. Absent quand --scm-connector-host n'est pas défini.

Pour la mise à l'échelle automatique, choisissez la série qui correspond à votre style de mise à l'échelle et gâtez-la avant qu'elle n'alimente le scaler :

  • Mise à l'échelle basée sur la profondeur de file d'attente : alimenter claude_code_self_hosted_orchestrator_pool_pending_sessions dans votre HPA ou scaler KEDA, pas queue_pending_sessions.
  • Mise à l'échelle basée sur la capacité : mettre à l'échelle sur le ratio des active_sessions du runner à capacity.
  • Gâter sur connected : filtrer la requête avec claude_code_self_hosted_orchestrator_connected == 1 par instance, afin que la valeur obsolète d'un réplica déconnecté n'alimente pas le scaler.

Pendant une panne d'interrogation complète, chaque réplica déconnecté, la requête gâtée ne retourne aucune donnée. HPA maintient le nombre de réplicas actuel sur une métrique manquante, mais le scaler Prometheus de KEDA à son ignoreNullValues: "true" par défaut lit le résultat vide comme zéro et réduit ; définir ignoreNullValues: "false" sur le ScaledObject, éventuellement avec un plancher de réplicas fallback.

Le PodMonitor Prometheus Operator suivant couvre les deux processus. Il sélectionne les pods par l'étiquette app.kubernetes.io/part-of: claude-code-self-hosted-runner et le port nommé health que la recette Kubernetes définit ; ajustez les espaces de noms pour correspondre à votre déploiement :

# Exemple PodMonitor Prometheus Operator pour le runner + orchestrateur
# Claude Code auto-hébergé. Ajustez les sélecteurs d'espace de noms et
# d'étiquettes pour correspondre à votre déploiement. À la fois le runner
# et l'orchestrateur servent /metrics sur leur --health-port (par défaut 8080).
apiVersion: monitoring.coreos.com/v1
kind: PodMonitor
metadata:
  name: claude-code-self-hosted-runner
  namespace: monitoring
spec:
  namespaceSelector:
    matchNames:
      - claude-runners
  selector:
    matchExpressions:
      # Correspond au Deployment du runner à partir de la recette Kubernetes,
      # plus tous les Jobs de runner à la demande et pods d'orchestrateur que
      # vous étiquetez de la même manière et donnez un containerPort nommé 'health'.
      - key: app.kubernetes.io/part-of
        operator: In
        values: [claude-code-self-hosted-runner]
  podMetricsEndpoints:
    - port: health
      path: /metrics
      interval: 30s

Ces exemples de règles d'alerte sont un point de départ ; affinez les seuils pour la taille de votre flotte :

# Exemple de règles d'alerte Prometheus pour le runner + orchestrateur
# Claude Code auto-hébergé. Affinez les seuils pour la taille de votre flotte et vos SLO.
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 }} n'a pas interrogé depuis >60s"
      - alert: ClaudeRunnerVersionDrift
        expr: count(count by (version) (claude_code_self_hosted_runner_info)) > 1
        for: 30m
        labels: {severity: info}
        annotations:
          summary: "Les runners exécutent des versions mixtes"
      - 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 défaillances d'init de session en 10m (hook checkout / git / token / crash pré-init)"
      - 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 échouant ({{ $value | humanize }}/s sur 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 défaillances du hook SessionStart en 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: "L'orchestrateur {{ $labels.pod }} ne peut pas atteindre le plan de contrôle Anthropic"
      - alert: ClaudeOrchestratorPollStale
        expr: claude_code_self_hosted_orchestrator_last_poll_age_seconds > 90
        for: 2m
        labels: {severity: warning}
        annotations:
          summary: "L'orchestrateur {{ $labels.pod }} n'a pas interrogé depuis >90s (la boucle d'interrogation attend l'exécution du hook)"
      - alert: ClaudeOrchestratorCircuitBroken
        expr: claude_code_self_hosted_orchestrator_queue_circuit_broken_sessions > 0
        for: 1m
        labels: {severity: critical}
        annotations:
          summary: "{{ $value }} sessions circuit-broken — le hook spawn-runner est répétitivement non-réessayable ; corriger l'infra puis réessayer à partir de l'onglet Activity"
      - alert: ClaudeOrchestratorPollErrors
        expr: sum by (pod) (rate(claude_code_self_hosted_orchestrator_poll_errors_total[5m])) > 0
        for: 2m
        labels: {severity: warning}
        annotations:
          summary: "L'orchestrateur {{ $labels.pod }} : PollSpawnHints échouant ({{ $value | humanize }}/s sur 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: "L'orchestrateur {{ $labels.pod }} : >3 défaillances du hook spawn-runner en 5m"

Transmettre les métriques de l'enfant de session

Chaque session s'exécute dans son propre processus enfant avec ses propres métriques OpenTelemetry ; à --capacity au-dessus d'un, le runner réécrit comment ces métriques enfants sont exposées. Définir OTEL_METRICS_EXPORTER=prometheus sur l'hôte du runner et CLAUDE_CODE_ENABLE_TELEMETRY=1 dans l'environnement de la session, par exemple à partir de votre script wrapper ou de l'environnement propre du runner, que les sessions héritent, réexpose les instruments de compteur et de jauge de chaque enfant sur le point de terminaison /metrics propre du runner, aux côtés de la série du runner. Le runner réécrit l'exporteur de l'enfant pour pousser sur OTLP vers un récepteur loopback uniquement sur le port de santé, étiquette chaque série avec les étiquettes session_id et client_platform, et expulse la série d'une session quand cette session se termine. Les histogrammes ne passent pas, et une métrique enfant dont le nom entrerait en collision avec le préfixe propre du runner est supprimée.

À la --capacity 1 par défaut, la réécriture ne s'applique pas : l'enfant de la session lie son propre point de terminaison Prometheus sur le port 9464 comme d'habitude.

Sémantique du compteur de cycle de vie de session

Les compteurs sessions_started_total, sessions_completed_total, sessions_failed_total et sessions_interrupted_total classent chaque session par la façon dont elle s'est terminée. Chaque enfant de session généré incrémente sessions_started_total au moment du lancement, et exactement l'un des trois autres incrémente à la sortie, donc sessions_started_total moins la somme des trois autres égale le nombre d'enfants de session actuellement en cours d'exécution.

  • completed : la session s'est terminée proprement. Cela couvre l'enfant se terminant de lui-même avec le code 0, la session étant archivée ou supprimée tandis que l'enfant était toujours connecté, et le runner libérant le créneau comme une remise propre : une libération inactive, un délai d'attente de démarrage ou une désassignation côté serveur que la boucle d'interrogation a remarquée avant la sortie de l'enfant. Incrémente sessions_completed_total.
  • failed : l'enfant s'est terminé de lui-même avec un code non-zéro, soit un crash soit une défaillance de configuration après le lancement. Incrémente sessions_failed_total.
  • interrupted : le runner a terminé l'enfant pour une raison opérationnelle qui n'est ni un succès de session ni une faute du runner, comme un drainage ou le watchdog de durée de vie maximale --kill-session-after-min. Un redémarrage roulant Kubernetes envoyant SIGTERM est un exemple de drainage. Incrémente sessions_interrupted_total.

Le CLAUDE_RUNNER_EXIT_REASON du hook post-session n'utilise pas cette classification pour les remises propres. Le hook signale une libération inactive, un délai d'attente de démarrage et une désassignation serveur comme interrupted, puisque du point de vue du hook le runner a tué l'enfant, tandis que les compteurs ci-dessus enregistrent ces mêmes événements comme completed, puisque rien n'a mal tourné et le créneau a été remis proprement. Si vous réconciliez les reçus du hook directement contre sessions_completed_total, vous sous-comptez les complétions. Utilisez le hook pour les garanties par session et les compteurs pour les taux agrégés.

Sur un environnement unique, --capacity 1 avec le --drain-grace-sec 0 par défaut, chaque processus runner se termine peu de temps après la fin de sa session unique. sessions_completed_total, sessions_failed_total et sessions_interrupted_total n'incrémentent qu'à la fin de la session, juste avant cette sortie, donc une récupération Prometheus toutes les 15 à 60 secondes attrape rarement l'incrément avant que la série du runner ne disparaisse ; ces trois compteurs de fin de session sont les compteurs terminaux auxquels le reste de cette section se réfère. sessions_started_total incrémente au lancement et reste visible pendant la durée de vie de la session, donc il s'affiche de manière fiable, mais sur un environnement unique il se lit plus proche de « sessions actuellement en cours d'exécution » qu'un compte cumulatif.

Utilisez la série dans ce tableau pour l'objectif correspondant au lieu des compteurs terminaux :

Objectif Utiliser
Débit claude_code_self_hosted_orchestrator_spawn_hooks_total{result="ok"}, un compteur sur l'orchestrateur de longue durée qui incrémente une fois par hook spawn-runner réussi et reste significatif sous rate(). Il compte les invocations de hook plutôt que les sessions, donc le préchauffage et les générations répétées pour la même session divergent de la session compte.
Utilisation sum(claude_code_self_hosted_runner_active_sessions) contre sum(claude_code_self_hosted_runner_capacity), les deux jauges valides à chaque récupération indépendamment de la durée de vie du runner
Arriéré claude_code_self_hosted_orchestrator_pool_pending_sessions pour la profondeur de file d'attente, et claude_code_self_hosted_orchestrator_queue_circuit_broken_sessions, alerter si au-dessus de zéro
Défaillances claude_code_self_hosted_runner_sessions_failed_total, meilleur effort : les vrais crashes après le lancement l'incrémentent, et rate() est significatif sur les runners qui survivent à leurs sessions avec --drain-grace-sec au-dessus de 0. Un environnement unique a le même problème de fenêtre de récupération que les autres compteurs terminaux, donc traitez toute valeur non-zéro que vous voyez comme valant la peine d'être enquêtée. Les défaillances avant le lancement, comme une défaillance du hook checkout, la préparation git ou un problème de token, n'apparaissent que dans session_init_errors_total.

Les lignes orchestrator_* n'existent que sur les environnements exécutant l'orchestrateur à la demande. Sur une flotte fixe dont les runners survivent à leurs sessions, avec --drain-grace-sec au-dessus de 0, utilisez sum(rate(claude_code_self_hosted_runner_sessions_started_total[5m])) pour le débit ; sur une flotte unique cette série a le même problème de fenêtre de récupération que les compteurs terminaux, donc fiez-vous au compte de sessions en file d'attente à la place. Vérifiez l'arriéré sur l'onglet Activity de l'environnement, sur la page d'administration Cloud environments : les runners n'exportent pas une série de profondeur de file d'attente.

Pour le rapport de résultat par session, utilisez le hook post-session à la place : il se déclenche à chaque fin de session où un processus enfant a été généré, à part la terminaison abrupte du runner comme une préemption de VM, selon le contrat propre du hook.

Étapes suivantes