자체 호스팅 환경은 Team 및 Enterprise 플랜에서 공개 베타 상태이며, Owner가 Cloud environments 관리자 페이지에서 Allow self-hosted environments를 켜서 활성화합니다. 이 페이지는 플래그 및 메트릭 참조이며, 설정은 빠른 시작을 참조하고 프로덕션 배포는 Deploy to production에서 플릿 레시피를 참조하세요.
/workspace 및 ~/.claude와 같은 기본값을 가정합니다. 설치된 버전에서 권한 있는 목록을 보려면 claude self-hosted-runner --help를 실행하세요.
메트릭 시리즈 및 일부 API 필드는 여전히 이 페이지에서 환경이라고 부르는 것을 pool이라고 사용합니다. 두 용어 모두 동일한 것을 나타냅니다. 환경 ID는 pool_id 필드이며, ccpool_... 형식입니다: 이 페이지에서 pool 식별자를 표시하는 곳마다 환경을 나타냅니다. CLI 플래그 및 환경 변수는 --environment-secret-file과 같이 environment로 표기합니다. 더 이상 사용되지 않는 pool 표기법은 여전히 작동하며, --environment-secret-file 행에서 설명합니다.
Runner CLI 플래그
대부분의 플래그에는 해당하는 환경 변수가 있습니다. 둘 다 설정된 경우 플래그가 우선합니다. 기간 플래그는 CLI에서 분 또는 초를 사용하지만, 쌍을 이루는 환경 변수는 항상 밀리초 단위이며_MS 접미사로 표시되고, 기본값 열은 플래그의 단위를 표시합니다: --exit-if-unused-min 10은 SELF_HOSTED_RUNNER_IDLE_SHUTDOWN_MS=600000과 동일하며, SELF_HOSTED_RUNNER_STARTUP_TIMEOUT_MS: "15"와 같은 Helm 값은 15분 기본값이 아닌 15밀리초를 의미합니다.
대부분의 기간 플래그에는 최대값이 있으며, 각 타임아웃을 런타임의 32비트 타이머 상한인 약 24.85일 이내로 유지하도록 선택됩니다.
--*-min 플래그는 10080분(7일)에서 상한선을 설정합니다. --drain-grace-sec는 604800초(역시 7일)에서 상한선을 설정합니다. --drain-wait-sec는 86400초(24시간)에서 상한선을 설정합니다. --session-stop-grace-sec 및 --post-session-hook-timeout-sec는 상한선이 없습니다. 상한선을 초과하는 동작은 표면별로 다릅니다:
- 플래그: 시작이 오류로 실패합니다.
- 환경 변수: 러너는 값을 거부하는 대신 타이머 상한선으로 고정합니다.
오케스트레이터 CLI 플래그
self-hosted-runner orchestrator 서브명령은 on-demand runners를 생성하며, --api-url, --environment-secret-file, --hooks-dir, --health-port 및 --log-level을 러너와 동일한 기본값으로 허용하며, 러너의 플래그에 하나가 있는 경우 동일한 환경 변수를 허용합니다. 단, --hooks-dir은 필수이며 spawn-runner 훅을 포함해야 합니다. 또한 자체 플래그를 사용합니다:
SCM 커넥터 플래그
오케스트레이터는 Anthropic의 제어 평면에 대한 상시 WebSocket 연결을 유지할 수 있으므로 저장소 선택기 및 분기 또는 ref 리졸버와 같은 호스팅된 사전 세션 흐름이 네트워크 내부에서만 라우팅 가능한 GitHub Enterprise Server 호스트에 도달할 수 있습니다. 커넥터는--scm-connector-host를 설정하지 않으면 꺼져 있습니다.
커넥터는 오케스트레이터의 기존 환경 비밀로 인증하고 자동으로 다시 연결합니다: 끊어진 연결에서 지수 백오프를 사용하거나, 다른 오케스트레이터 복제본이 이미 이를 보유하고 있기 때문에 제어 평면이 연결을 닫을 때 고정 30초 지연입니다.
환경 변수 전용 설정
이러한 러너 설정은 환경에서만 읽으며 대부분의 배포가 기본값으로 남겨두는 동작을 다룹니다:텔레메트리
세션 자식은 끄지 않으면 Anthropic에 운영 텔레메트리를 전송합니다. 코드 또는 저장소 내용은 전송되지 않습니다. 러너 프로세스에서 텔레메트리 변수를 설정하세요. 러너는 서버 제공 환경 변수를 적용한 후 다시 주장하므로 운영자의 설정이 항상 우선합니다. 한 가지 제어는 자체 호스팅 환경에만 해당됩니다:CLAUDE_CODE_BYOC_ENABLE_DATADOG=1은 Datadog 운영 메트릭을 옵트인하며, 이는 자체 호스팅 환경에서 기본적으로 꺼져 있습니다. 일반 Claude Code 텔레메트리 제어인 DISABLE_TELEMETRY, DO_NOT_TRACK, DISABLE_ERROR_REPORTING 및 CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC은 environment variable reference에서 문서화된 대로 세션 자식에 적용됩니다. DISABLE_GROWTHBOOK은 관련이 있지만 다릅니다: DISABLE_GROWTHBOOK=1을 설정하면 기능 플래그 페칭이 비활성화되고, DISABLE_TELEMETRY도 설정되지 않으면 텔레메트리가 켜져 있습니다.
CLAUDE_CODE_ENABLE_TELEMETRY는 관련이 없습니다: Monitoring에서 설명한 대로 자신의 수집기로 OpenTelemetry 내보내기를 활성화하며, Anthropic의 분석을 제어하지 않습니다.
상태 엔드포인트
러너는 구성된 상태 포트에서GET /healthz를 제공합니다. 응답은 프로세스가 살아 있을 때마다 200 OK이며, 폴 루프가 어떤 상태에 있든 관계없이, 이 엔드포인트의 HTTP 프로브는 죽은 프로세스만 감지합니다. JSON 본문은 현재 상태를 설명합니다:
last_poll_age_ms를 생존 신호로 사용하세요. 무한정 증가하는 값은 폴 루프가 고착되었음을 나타냅니다. last_poll_at 및 last_poll_age_ms 모두 첫 번째 폴이 완료될 때까지 null입니다.
오케스트레이터는 상태 포트에서 자체 /healthz를 제공합니다. 엔드포인트는 항상 200을 반환하며, 본문은 가장 최근 폴이 성공했는지 여부를 보고하는 connected 필드와 queue_counts의 상태별 스폰 큐 수를 전달합니다. 상태 코드가 아닌 connected에 준비 및 경고를 게이트하세요.
SCM connector가 구성되면, 오케스트레이터의 /healthz 본문도 scm_connector_connected 및 connected, last_connected_at, last_error, reconnects 및 requests_forwarded를 포함하는 scm_connector 객체를 전달합니다. --scm-connector-host가 설정되지 않으면 두 필드 모두 null입니다.
Prometheus 메트릭
각 러너는/healthz와 동일한 포트에서 GET /metrics에서 Prometheus 메트릭을 제공합니다. 주요 시리즈:
오케스트레이터는
/healthz와 동일한 포트에서 GET /metrics에서 자체 시리즈를 제공합니다:
자동 스케일링의 경우 스케일링 스타일과 일치하는 시리즈를 선택하고 스케일러에 공급하기 전에 게이트하세요:
- 큐 깊이 스케일링:
queue_pending_sessions이 아닌claude_code_self_hosted_orchestrator_pool_pending_sessions을 HPA 또는 KEDA 스케일러에 공급하세요. - 용량 스케일링: 러너의
active_sessions과capacity의 비율에 따라 스케일하세요. connected에 게이트: 쿼리를 인스턴스당claude_code_self_hosted_orchestrator_connected == 1로 필터링하여 연결이 끊긴 복제본의 오래된 값이 스케일러에 공급되지 않도록 하세요.
ignoreNullValues: "true"에서 빈 결과를 0으로 읽고 축소합니다. ScaledObject에서 ignoreNullValues: "false"를 설정하고, 선택적으로 fallback 복제본 바닥으로 설정하세요.
다음 Prometheus Operator PodMonitor는 두 프로세스를 모두 다룹니다. app.kubernetes.io/part-of: claude-code-self-hosted-runner 레이블 및 Kubernetes recipe가 설정하는 명명된 health 포트로 포드를 선택합니다. 배포와 일치하도록 네임스페이스를 조정하세요:
세션 자식 메트릭 통과
각 세션은 자체 자식 프로세스에서 자체 OpenTelemetry 메트릭으로 실행됩니다.--capacity가 1 이상일 때, 러너는 이러한 자식 메트릭이 노출되는 방식을 다시 작성합니다. 러너 호스트에서 OTEL_METRICS_EXPORTER=prometheus를 설정하고 세션의 환경에서 CLAUDE_CODE_ENABLE_TELEMETRY=1을 설정하면(예: wrapper script 또는 러너의 자체 환경에서, 세션이 상속함), 각 자식의 카운터 및 게이지 도구를 러너의 자체 /metrics 엔드포인트에 다시 노출하며, 러너의 시리즈와 함께 노출합니다. 러너는 자식의 내보내기를 루프백 전용 수신기로 OTLP를 통해 상태 포트로 푸시하도록 다시 작성하고, 각 시리즈에 session_id 및 client_platform 레이블을 태그하며, 해당 세션이 종료될 때 세션의 시리즈를 제거합니다. 히스토그램은 통과하지 않으며, 러너의 자체 접두사와 충돌하는 자식 메트릭은 삭제됩니다.
기본 --capacity 1에서 다시 작성이 적용되지 않습니다: 세션의 자식은 일반적으로 포트 9464에서 자체 Prometheus 엔드포인트를 바인딩합니다.
세션 라이프사이클 카운터 의미론
sessions_started_total, sessions_completed_total, sessions_failed_total 및 sessions_interrupted_total 카운터는 각 세션을 종료 방식으로 분류합니다. 생성된 모든 세션 자식은 생성 시 sessions_started_total을 증가시키고, 정확히 하나의 다른 세 개가 종료 시 증가하므로, sessions_started_total 빼기 다른 세 개의 합은 현재 실행 중인 세션 자식의 수와 같습니다.
completed: 세션이 깔끔하게 종료되었습니다. 이는 자식이 코드0으로 자체 종료, 자식이 여전히 연결된 동안 세션이 보관되거나 삭제됨, 그리고 러너가 슬롯을 깔끔하게 반환하는 경우(유휴 타임아웃, 은퇴 시간 또는--kill-session-after-min제한에서 세션을 해제하는 경우, 시작 타임아웃, 또는 자식이 종료되기 전에 폴 루프가 알아챈 서버 측 할당 해제)를 다룹니다.sessions_completed_total을 증가시킵니다.failed: 자식이 자체적으로 0이 아닌 코드로 종료되었으며, 충돌 또는 생성 후 설정 실패입니다.sessions_failed_total을 증가시킵니다.interrupted: 러너가 세션 성공도 러너 결함도 아닌 운영 이유로 자식을 종료했습니다(예: 드레인 또는--kill-session-after-min한계 후SELF_HOSTED_RUNNER_MAX_LIFETIME_GRACE_MS유예 기간이 끝날 때 여전히 러너에 남아 있던 세션을 종료함). Kubernetes 롤링 재시작이SIGTERM을 전송하는 것은 드레인의 한 예입니다.sessions_interrupted_total을 증가시킵니다.
--kill-session-after-min 한계에 도달한 모든 세션을 종료하고 sessions_interrupted_total에서 계산했습니다.
post-session 훅의 CLAUDE_RUNNER_EXIT_REASON은 이러한 깔끔한 슬롯 반환을 다르게 분류합니다. 훅은 해제, 시작 타임아웃 및 서버 할당 해제를 interrupted로 보고합니다. 러너가 자식을 중지했기 때문입니다. 이러한 카운터는 동일한 이벤트를 completed로 기록합니다. 슬롯이 깔끔하게 반환되었기 때문입니다.
훅 수신을 sessions_completed_total에 직접 조정하면 완료를 과소 계산합니다. 세션별 보장을 위해 훅을 사용하고 집계 비율을 위해 카운터를 사용하세요.
원샷 환경에서 --capacity 1과 기본 --drain-grace-sec 0을 사용하면, 각 러너 프로세스는 하나의 세션이 종료된 후 잠시 후 종료됩니다. sessions_completed_total, sessions_failed_total 및 sessions_interrupted_total은 세션 종료 시에만 증가하며, 그 종료 직전이므로, 15~60초마다 Prometheus 스크래핑은 러너의 시리즈가 사라지기 전에 증가를 거의 포착하지 못합니다. 이 세 개의 세션 종료 카운터는 이 섹션의 나머지 부분이 참조하는 터미널 카운터입니다. sessions_started_total은 생성 시 증가하고 세션의 수명 동안 표시되므로 안정적으로 표시되지만, 원샷 환경에서는 누적 수보다 “현재 실행 중인 세션”에 더 가깝게 읽힙니다.
대신 해당 목표에 대해 이 표의 시리즈를 사용하세요:
orchestrator_* 행은 on-demand orchestrator를 실행하는 환경에만 존재합니다. 세션을 능가하는 러너가 있는 고정 플릿에서 --drain-grace-sec 이상 0을 사용하면 처리량을 위해 sum(rate(claude_code_self_hosted_runner_sessions_started_total[5m]))을 사용하세요. 원샷 플릿에서 해당 시리즈는 터미널 카운터와 동일한 스크래핑 윈도우 문제를 가지므로 대신 대기 중인 세션 수에 의존하세요. 환경의 Activity 탭, Cloud environments 관리자 페이지에서 백로그를 확인하세요: 러너는 큐 깊이 시리즈를 내보내지 않습니다.
세션별 결과 보고의 경우 대신 post-session 훅을 사용하세요: VM 선점과 같은 갑작스러운 러너 종료를 제외하고 자식 프로세스가 생성된 모든 세션 종료에서 실행됩니다(훅의 자체 계약에 따름).
다음 단계
- Self-hosted environments: 환경, 러너 및 세션 모델입니다. quickstart 및 Deploy to production은 설정 및 운영을 보유합니다.
- Customize sessions: 래퍼 스크립트, 라이프사이클 훅 및 온디맨드 러너
- Verify session identity: 세션 토큰, 해당 클레임 및 확인 방법