Skip to main content
Самостоятельно размещаемые окружения находятся в публичной бета-версии на планах Team и Enterprise; Owner включает их, активируя Allow self-hosted environments на странице администратора Cloud environments. Эта страница является справочником по флагам и метрикам; см. quickstart для настройки и Deploy to production для рецептов флота.
Эта страница является справочником для двух процессов, которые вы запускаете в самостоятельно размещаемом окружении: runner, который выполняет Claude Code cloud sessions на ваших хостах, и опциональный orchestrator автомасштабирования, который запускает runners по мере поступления sessions в очередь. Каждый имеет свою таблицу флагов. Оба работают на хостах Linux или macOS, для которых значения по умолчанию, такие как /workspace и ~/.claude, предполагаются. Запустите claude self-hosted-runner --help для авторитетного списка на вашей установленной версии. Серии метрик и несколько полей API по-прежнему используют pool для того, что эти страницы называют окружением; оба термина обозначают одно и то же. ID окружения — это поле pool_id с формой ccpool_...: везде, где эти страницы показывают идентификатор pool, он обозначает окружение. Флаги CLI и переменные окружения пишут его как environment, например --environment-secret-file; устаревшие написания pool по-прежнему работают, как описывает строка --environment-secret-file.

Флаги CLI Runner

Большинство флагов имеют соответствующую переменную окружения. Когда установлены оба, флаг имеет приоритет. Флаги длительности принимают минуты или секунды в CLI, но связанная переменная окружения всегда в миллисекундах, обозначаемая суффиксом _MS, и столбец Default показывает единицу флага: --exit-if-unused-min 10 эквивалентно SELF_HOSTED_RUNNER_IDLE_SHUTDOWN_MS=600000, а значение Helm вроде SELF_HOSTED_RUNNER_STARTUP_TIMEOUT_MS: "15" означает 15 миллисекунд, а не 15-минутное значение по умолчанию. Большинство флагов длительности имеют максимум, выбранный для сохранения каждого timeout в потолке 32-битного таймера runtime примерно 24,85 дня. Флаги --*-min ограничены 10080 минутами, 7 дней; --drain-grace-sec на 604800 секунд, также 7 дней; и --drain-wait-sec на 86400 секунд, 24 часа. --session-stop-grace-sec и --post-session-hook-timeout-sec не ограничены. Превышение лимита ведет себя по-разному в зависимости от поверхности:
  • Флаг: запуск не удается с ошибкой.
  • Переменная окружения: runner зажимает значение до потолка таймера вместо его отклонения.

Таймаут запуска сессии

Если сессия потеряла свой слот во время хода, например /code-review, обновите runner и дочерний бинарный файл до v2.1.309 или новее. С v2.1.299 по v2.1.308 runner освобождал сессию, даже посреди хода, если таймаут запуска истекал без сообщения user или assistant. С --startup-timeout-min <n> runner освобождает слот сессии, если её дочерний процесс не инициализировался в течение <n> минут после клонирования. Во время хода, начавшегося до инициализации дочернего процесса, сессия сохраняет свой слот, пока не пройдёт <n> минут без единой строки в канале активности дочернего процесса. После инициализации дочернего процесса runner сбрасывает этот отсчёт, и освобождением управляет --release-idle-session-min. Чтобы ограничить сессию, дочерний процесс которой жив, но завис, задайте --kill-session-after-min.

Списки правил авторежима

--server-auto-mode-lists позволяет решить, какие правила классификатора авторежима, поступающие извне runner, применяются к сессиям на ваших runner. Управляющий уровень Anthropic может отправлять списки правил вместе с сессией и просить runner применить их. Некоторые записи могут быть правилами, написанными администратором вашей организации. Списки называются environment, soft_deny и allow:
  • environment: запись может заставить классификатор разрешать как больше, так и меньше.
  • soft_deny: запись блокирует действие, если только пользователь явно не попросил о нём или не применяется исключение allow.
  • allow: исключения для записей soft_deny.
Значение флага определяет, какие списки применяет runner:
  • no-allow: значение по умолчанию. Применяет environment и soft_deny и не применяет allow. Запись environment по-прежнему может заставить классификатор разрешать больше, поэтому значение по умолчанию не исключает всех ослаблений.
  • all: применяет все три списка.
  • none: не применяет ни один из них. Выберите none, чтобы исключить любые ослабления из этих списков. При этом также отбрасываются ограничения soft_deny.
Никакая настройка runner не заставляет управляющий уровень просить runner применить списки. Если он не просит, сессии не получают ни одного списка, что бы вы ни установили. Чтобы узнать, что произошло, запустите runner с --log-level debug. Тогда для каждой сессии runner записывает в лог строку, содержащую the server asked this runner to apply, или строку, содержащую the server did not ask this runner to apply the auto mode lists it sends.

Флаги CLI Orchestrator

Подкоманда self-hosted-runner orchestrator, которая порождает on-demand runners, принимает --api-url, --environment-secret-file, --hooks-dir, --health-port и --log-level с теми же значениями по умолчанию, что и runner и, где флаг runner имеет один, ту же переменную окружения, за исключением того, что --hooks-dir требуется и должен содержать hook spawn-runner. Он также принимает свои собственные флаги:

Флаги SCM connector

Соединитель SCM недоступен, поэтому оставьте флаги в этом разделе неустановленными. Если вы установите --scm-connector-host, соединение не открывается, и orchestrator продолжает его переподключать. Runners по-прежнему запускаются по мере поступления сеансов в очередь. Соединитель — это постоянное подключение WebSocket от orchestrator к плоскости управления Anthropic. Он разработан для того, чтобы позволить размещенным предсеансовым потокам, таким как средство выбора репозитория и средство разрешения ветви или ссылки, достичь хоста GitHub Enterprise Server, который маршрутизируется только изнутри вашей сети. См. Network requirements на странице GitHub Enterprise Server для получения информации о том, что требуется этим потокам. При каждой попытке подключения orchestrator отправляет свой существующий секрет окружения, и он автоматически переподключается с экспоненциальной задержкой, ограниченной 30 секундами плюс jitter.

Параметры только для переменных окружения

Эти параметры runner читаются только из окружения и охватывают поведение, которое большинство развертываний оставляют по умолчанию:

Телеметрия

Дочерние процессы сеанса отправляют операционную телеметрию в Anthropic, если вы её не отключите. Никакой код или содержимое репозитория не отправляется. Установите переменные телеметрии на процесс runner; runner переустанавливает их после применения переменных окружения, предоставленных сервером, поэтому параметр оператора всегда имеет приоритет. Один элемент управления специфичен для самостоятельно размещаемых сред: CLAUDE_CODE_BYOC_ENABLE_DATADOG=1 выбирает метрики операционной деятельности Datadog, которые по умолчанию отключены в самостоятельно размещаемых средах. Общие элементы управления телеметрией Claude Code, DISABLE_TELEMETRY, DO_NOT_TRACK, DISABLE_ERROR_REPORTING и CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC, применяются к дочерним процессам сеанса, как задокументировано в справочнике переменных окружения. DISABLE_GROWTHBOOK связан, но отличается: установка DISABLE_GROWTHBOOK=1 отключает выборку флагов функций, и телеметрия остается включенной, если также не установлен DISABLE_TELEMETRY. CLAUDE_CODE_ENABLE_TELEMETRY не связан: он включает экспорт OpenTelemetry на ваш собственный сборщик, как описано в Monitoring, и не контролирует аналитику Anthropic.

Конечная точка здоровья

Runner служит GET /healthz на настроенном порту здоровья. Ответ 200 OK всякий раз, когда процесс живой, независимо от состояния цикла опроса, поэтому зонд HTTP на этой конечной точке обнаруживает только мертвый процесс. Тело JSON описывает текущее состояние:
Используйте last_poll_age_ms как сигнал живости в пользовательских зондах; значение, которое растет без ограничений, указывает на то, что цикл опроса застрял. Оба last_poll_at и last_poll_age_ms равны null до завершения первого опроса. Собственный /healthz orchestrator на его порту здоровья всегда возвращает 200. Тело несет поле connected, сообщающее, успешен ли последний опрос, плюс количество очереди порождения для каждого состояния в queue_counts. Чтобы узнать, почему connected равно false, прочитайте поле верхнего уровня last_error, которое сбрасывается в null при каждом успешном опросе. Ограничьте готовность и оповещение на connected вместо кода состояния. Когда SCM connector настроен, тело /healthz orchestrator также несет scm_connector_connected и объект scm_connector с connected, last_connected_at, last_error, reconnects и requests_forwarded. Оба поля равны null, когда --scm-connector-host не установлен.

Метрики Prometheus

Каждый runner отдаёт метрики Prometheus по GET /metrics на том же порту, что и /healthz. Основные серии: Оркестратор отдаёт собственные серии по GET /metrics на том же порту, что и его /healthz: Для автомасштабирования выберите серию, соответствующую вашему подходу к масштабированию, и отфильтруйте её, прежде чем передавать в механизм масштабирования:
  • Масштабирование по глубине очереди: передавайте в HPA или KEDA claude_code_self_hosted_orchestrator_pool_pending_sessions, а не queue_pending_sessions.
  • Масштабирование по ёмкости: масштабируйте по отношению active_sessions runner к capacity.
  • Фильтрация по connected: фильтруйте запрос условием claude_code_self_hosted_orchestrator_connected == 1 для каждого экземпляра, чтобы устаревшее значение отключённой реплики не попадало в механизм масштабирования.
Во время полного сбоя опроса, когда все реплики отключены, отфильтрованный запрос не возвращает данных. HPA сохраняет текущее число реплик при отсутствии метрики, однако Prometheus scaler в KEDA со значением по умолчанию ignoreNullValues: "true" интерпретирует пустой результат как ноль и уменьшает число реплик; задайте ignoreNullValues: "false" в ScaledObject, при необходимости вместе с минимальным числом реплик fallback. Следующий PodMonitor для Prometheus Operator охватывает оба процесса. Он выбирает поды по метке app.kubernetes.io/part-of: claude-code-self-hosted-runner и именованному порту health, которые задаёт рецепт для Kubernetes; скорректируйте пространства имён в соответствии с вашим развёртыванием:

Примеры правил оповещений

Эти примеры правил оповещений — отправная точка; настройте пороговые значения под размер вашего парка:

Оповещения о потере runner и ожидающих сессиях

Для фиксированного парка загрузите ClaudeRunnersBelowFloor. При использовании runner по требованию вместо этого загрузите ClaudeOrchestratorSessionsWaiting и ClaudeOrchestratorQueueWaitHigh.

Оповещение о потере runner в фиксированном парке

ClaudeRunnersBelowFloor срабатывает, когда в течение 10 минут зарегистрированных runner, с которых собираются метрики, остаётся меньше минимального порога:
  • Минимальный порог: задайте 2 в expr примерно равным половине числа реплик с округлением вверх. При трёх репликах оставьте 2, и оповещение сработает, когда останется один runner или ни одного.
  • Пространство имён: замените claude-runners в matcher и в labels и скопируйте оповещение для каждого дополнительного пространства имён. Если у ваших целей нет метки namespace, удалите matcher и метку, иначе оповещение получит 0 и сработает.
  • ClaudeRunnerPollStale и ClaudeRunnerPollErrors: оставьте их загруженными из примеров правил оповещений, поскольку ClaudeRunnersBelowFloor по-прежнему учитывает runner, который не может выполнить опрос

Оповещение об ожидании сессиями runner по требованию

ClaudeOrchestratorSessionsWaiting срабатывает, когда число сессий, ожидающих runner, остаётся выше 0 в течение 10 минут. ClaudeOrchestratorQueueWaitHigh срабатывает, когда более 1% ожиданий в очереди за последние 10 минут превысили 160 секунд и это сохраняется в течение 5 минут:
  • Порог: если какая-то сессия ожидает постоянно, поднимите > 0 в ClaudeOrchestratorSessionsWaiting выше значения, которое вы обычно наблюдаете
  • ClaudeOrchestratorDisconnected: оставьте его загруженным из примеров правил оповещений, поскольку ClaudeOrchestratorSessionsWaiting перестаёт срабатывать примерно через 2 минуты после отключения последнего оркестратора в пространстве имён

Проброс метрик дочерних процессов сессий

Каждая сессия выполняется в собственном дочернем процессе со своими метриками OpenTelemetry; при --capacity больше единицы runner изменяет способ публикации этих дочерних метрик. Если задать OTEL_METRICS_EXPORTER=prometheus на хосте runner и CLAUDE_CODE_ENABLE_TELEMETRY=1 в окружении сессии, например из вашего скрипта-обёртки или в собственном окружении runner, которое наследуют сессии, то инструменты типа counter и gauge каждого дочернего процесса будут повторно опубликованы на собственном эндпоинте /metrics runner рядом с сериями самого runner. Runner перенастраивает экспортёр дочернего процесса на отправку по OTLP в приёмник на порту health, доступный только через loopback, помечает каждую серию метками session_id и client_platform и удаляет серии сессии, когда эта сессия завершается. Гистограммы не пробрасываются, а дочерняя метрика, имя которой конфликтовало бы с собственным префиксом runner, отбрасывается. При значении по умолчанию --capacity 1 эта перенастройка не применяется: дочерний процесс сессии, как обычно, открывает собственный эндпоинт Prometheus на порту 9464.

Сопоставление метрик сессии с метриками runner

Чтобы разместить собственные метрики сессии рядом с claude_code_self_hosted_runner_session_idle_seconds, выполняйте соединение по session_id runner:
  • При --capacity больше единицы: соединяйте напрямую. На /metrics runner серии сессии содержат тот же session_id, что и эта метрика, в форме session_....
  • При --capacity 1: соединяйте по преобразованному ccr_session_id. По умолчанию каждая метрика Claude Code на порту 9464 содержит эту метку, в которой хранится ID сессии в форме cse_.... В новой метке замените её префикс cse_ на session_, чтобы получить session_id runner. Собственный session_id метрики содержит собственный session.id Claude Code, который не совпадает ни с одной серией runner.

Семантика счётчиков жизненного цикла сессий

Счётчики sessions_started_total, sessions_completed_total, sessions_failed_total и sessions_interrupted_total классифицируют каждую сессию по тому, как она завершилась. Каждый запущенный дочерний процесс сессии увеличивает sessions_started_total в момент запуска, и ровно один из остальных трёх счётчиков увеличивается при выходе, поэтому sessions_started_total минус сумма остальных трёх равна числу дочерних процессов сессий, выполняющихся в данный момент.
  • completed: сессия завершилась штатно. Сюда относятся: самостоятельный выход дочернего процесса с кодом 0; архивация или удаление сессии, пока дочерний процесс ещё был подключён; штатное освобождение слота runner: освобождение сессии по таймауту простоя, по времени вывода из эксплуатации или по лимиту --kill-session-after-min; таймаут запуска; либо снятие назначения на стороне сервера, которое цикл опроса заметил до выхода дочернего процесса. Увеличивает sessions_completed_total.
  • failed: дочерний процесс самостоятельно завершился с ненулевым кодом — из-за падения или сбоя настройки после запуска. Увеличивает sessions_failed_total.
  • interrupted: runner завершил дочерний процесс по эксплуатационной причине, которая не является ни успехом сессии, ни ошибкой runner, например при выводе из работы (drain) или при завершении сессии, которая всё ещё находилась на runner по истечении окна отсрочки SELF_HOSTED_RUNNER_MAX_LIFETIME_GRACE_MS после её лимита --kill-session-after-min. Поэтапный перезапуск в Kubernetes с отправкой SIGTERM — один из примеров вывода из работы. Увеличивает sessions_interrupted_total.
До версии v2.1.260 runner завершал каждую сессию, достигшую лимита --kill-session-after-min, и учитывал её в sessions_interrupted_total. Переменная CLAUDE_RUNNER_EXIT_REASON хука post-session классифицирует штатные передачи иначе. Хук сообщает о них как об interrupted, поскольку runner остановил дочерний процесс: это освобождение, таймаут запуска, снятие назначения сервером, а также архивация или удаление, которые первым заметил опрос. Эти счётчики записывают те же события как completed, поскольку слот был освобождён штатно. Если сверять получение хуков непосредственно с sessions_completed_total, число завершений окажется заниженным. Используйте хук для гарантий на уровне отдельных сессий, а счётчики — для агрегированных показателей. В одноразовом окружении, с --capacity 1 и значением по умолчанию --drain-grace-sec 0, каждый процесс runner завершается через мгновение после окончания его единственной сессии. sessions_completed_total, sessions_failed_total и sessions_interrupted_total увеличиваются только в конце сессии, непосредственно перед этим выходом, поэтому сбор метрик Prometheus каждые 15–60 секунд редко успевает зафиксировать приращение до того, как серии runner исчезнут; именно эти три счётчика окончания сессии далее в этом разделе называются терминальными. sessions_started_total увеличивается при запуске и остаётся видимым на протяжении всей сессии, поэтому он надёжно появляется, однако в одноразовом окружении он скорее отражает «сессии, выполняющиеся в данный момент», чем накопительное значение. Для соответствующей цели используйте серии из этой таблицы вместо терминальных счётчиков: Строки orchestrator_* существуют только в окружениях, использующих оркестратор по требованию. В фиксированном парке, runner которого переживают свои сессии при --drain-grace-sec больше 0, используйте sum(rate(claude_code_self_hosted_runner_sessions_started_total[5m])) для пропускной способности; в одноразовом парке у этой серии та же проблема окна сбора, что и у терминальных счётчиков, поэтому полагайтесь на число сессий в очереди. Проверяйте очередь на вкладке Activity окружения на странице администрирования Cloud environments: runner не экспортируют серию глубины очереди. Для отчётности по итогам отдельных сессий используйте хук post-session: он срабатывает при каждом завершении сессии, для которой был запущен дочерний процесс, за исключением внезапного завершения runner, например при вытеснении VM, в соответствии с собственным контрактом хука.

Что дальше