Skip to main content
Lingkungan yang di-host sendiri berada dalam beta publik pada paket Team dan Enterprise; seorang Owner mengaktifkannya dengan mengaktifkan Allow self-hosted environments di halaman admin Cloud environments. Halaman ini adalah referensi flag dan metrik; lihat quickstart untuk setup dan Deploy to production untuk resep fleet.
Halaman ini adalah referensi untuk dua proses yang Anda jalankan dalam lingkungan yang di-host sendiri: runner, yang mengeksekusi Claude Code cloud sessions di host Anda, dan orchestrator autoscaling opsional, yang memulai runner saat session antri. Masing-masing memiliki tabel flag-nya sendiri. Keduanya berjalan di host Linux atau macOS, yang default seperti /workspace dan ~/.claude asumsikan. Jalankan claude self-hosted-runner --help untuk daftar otoritatif pada versi terinstal Anda. Seri metrik dan beberapa field API masih menggunakan pool untuk apa yang halaman ini sebut lingkungan; kedua istilah menamakan hal yang sama. ID lingkungan adalah field pool_id, dengan bentuk ccpool_...: di mana pun halaman ini menunjukkan identifier pool, itu menamakan lingkungan. Flag CLI dan variabel lingkungan mengejanya environment, seperti --environment-secret-file; ejaan pool yang sudah usang masih berfungsi, seperti yang dijelaskan baris --environment-secret-file.

Flag CLI Runner

Sebagian besar flag memiliki variabel lingkungan yang sesuai. Ketika keduanya diatur, flag mengambil prioritas. Flag durasi mengambil menit atau detik di CLI, tetapi variabel lingkungan yang dipasangkan selalu dalam milidetik, ditunjukkan oleh suffix _MS, dan kolom Default menunjukkan unit flag: --exit-if-unused-min 10 setara dengan SELF_HOSTED_RUNNER_IDLE_SHUTDOWN_MS=600000, dan nilai Helm seperti SELF_HOSTED_RUNNER_STARTUP_TIMEOUT_MS: "15" berarti 15 milidetik, bukan default 15 menit. Sebagian besar flag durasi memiliki maksimum, dipilih untuk menjaga setiap timeout di dalam ceiling timer 32-bit runtime sekitar 24,85 hari. Flag --*-min cap pada 10080 menit, 7 hari; --drain-grace-sec pada 604800 detik, juga 7 hari; dan --drain-wait-sec pada 86400 detik, 24 jam. --session-stop-grace-sec dan --post-session-hook-timeout-sec tidak terbatas. Melampaui cap berperilaku berbeda per surface:
  • Flag: startup gagal dengan error.
  • Variabel lingkungan: runner menjepit nilai ke ceiling timer daripada menolaknya.

Timeout startup sesi

Jika sebuah sesi kehilangan slotnya selama giliran seperti /code-review, perbarui runner dan binary child ke v2.1.309 atau lebih baru. Dari v2.1.299 hingga v2.1.308, runner melepaskan sesi, bahkan di tengah giliran, begitu timeout startup terlewati tanpa pesan user atau assistant. Dengan --startup-timeout-min <n>, runner melepaskan slot sesi ketika child-nya belum diinisialisasi dalam <n> menit setelah cloning. Selama giliran yang dimulai sebelum child diinisialisasi, sesi mempertahankan slotnya hingga <n> menit berlalu tanpa satu baris pun di activity channel milik child. Setelah child diinisialisasi, runner mengosongkan hitungan tersebut dan --release-idle-session-min mengatur pelepasan. Untuk membatasi sesi yang child-nya hidup tetapi macet, atur --kill-session-after-min.

Daftar aturan auto mode

--server-auto-mode-lists memungkinkan Anda memutuskan aturan pengklasifikasi auto mode mana dari luar runner yang mencapai sesi di runner Anda. Control plane Anthropic dapat mengirim daftar aturan bersama sebuah sesi dan meminta runner untuk menerapkannya. Beberapa entri mungkin merupakan aturan yang ditulis oleh admin organisasi Anda. Daftarnya adalah environment, soft_deny, dan allow:
  • environment: sebuah entri dapat membuat pengklasifikasi mengizinkan lebih banyak maupun lebih sedikit.
  • soft_deny: sebuah entri memblokir tindakan kecuali pengguna secara eksplisit memintanya atau pengecualian allow berlaku.
  • allow: pengecualian terhadap entri soft_deny.
Nilai flag menentukan daftar mana yang diterapkan runner:
  • no-allow: default. Menerapkan environment dan soft_deny serta menahan allow. Entri environment tetap dapat membuat pengklasifikasi mengizinkan lebih banyak, sehingga default tidak mencegah setiap pelonggaran.
  • all: menerapkan ketiga daftar.
  • none: tidak menerapkan satu pun. Pilih none untuk mencegah setiap pelonggaran dari daftar-daftar ini. Ini juga menghilangkan pembatasan soft_deny.
Tidak ada pengaturan runner yang membuat control plane meminta runner menerapkan daftar tersebut. Ketika control plane tidak meminta, sesi tidak menerima daftar apa pun, apa pun yang Anda atur. Untuk melihat mana yang terjadi, mulai runner dengan --log-level debug. Untuk setiap sesi, runner kemudian mencatat ke log baris yang berisi the server asked this runner to apply, atau baris yang berisi the server did not ask this runner to apply the auto mode lists it sends.

Flag CLI Orchestrator

Subperintah self-hosted-runner orchestrator, yang menghasilkan on-demand runners, menerima --api-url, --environment-secret-file, --hooks-dir, --health-port, dan --log-level dengan default yang sama seperti runner dan, di mana flag runner memiliki satu, variabel lingkungan yang sama, kecuali bahwa --hooks-dir diperlukan dan harus berisi hook spawn-runner. Ini juga mengambil flag sendiri:

Flag SCM connector

SCM connector tidak tersedia, jadi biarkan flag di bagian ini tidak diatur. Jika Anda mengatur --scm-connector-host, koneksi tidak terbuka, dan orchestrator terus mencoba lagi. Runner masih dimulai saat session queue. Connector adalah koneksi WebSocket berdiri dari orchestrator ke control plane Anthropic. Dirancang untuk membiarkan hosted pre-session flows, seperti repository picker dan branch atau ref resolver, menjangkau host GitHub Enterprise Server yang hanya dapat dirutekan dari dalam jaringan Anda. Lihat Network requirements di halaman GitHub Enterprise Server untuk apa yang dibutuhkan flows tersebut. Pada setiap percobaan koneksi orchestrator mengirimkan rahasia lingkungan yang ada, dan itu mencoba lagi secara otomatis dengan exponential backoff, dibatasi pada 30 detik plus jitter.

Pengaturan variabel-lingkungan-saja

Pengaturan runner ini dibaca dari lingkungan saja dan mencakup perilaku yang sebagian besar deployment tinggalkan di default:

Telemetry

Child session mengirim telemetry operasional ke Anthropic kecuali Anda mematikannya. Tidak ada kode atau konten repositori yang dikirim. Atur variabel telemetry pada proses runner; runner re-assert mereka setelah menerapkan variabel lingkungan yang disediakan server, jadi pengaturan operator selalu mengambil prioritas. Satu kontrol spesifik untuk lingkungan yang di-host sendiri: CLAUDE_CODE_BYOC_ENABLE_DATADOG=1 opt in ke metrik operasional Datadog, yang off secara default dalam lingkungan yang di-host sendiri. Kontrol telemetry Claude Code umum, DISABLE_TELEMETRY, DO_NOT_TRACK, DISABLE_ERROR_REPORTING, dan CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC, berlaku untuk child session seperti yang didokumentasikan dalam referensi variabel lingkungan. DISABLE_GROWTHBOOK terkait tetapi berbeda: mengatur DISABLE_GROWTHBOOK=1 menonaktifkan pengambilan feature-flag, dan telemetry tetap on kecuali DISABLE_TELEMETRY juga diatur. CLAUDE_CODE_ENABLE_TELEMETRY tidak terkait: itu mengaktifkan export OpenTelemetry ke collector Anda sendiri, seperti yang dijelaskan dalam Monitoring, dan tidak mengontrol analytics Anthropic.

Health endpoint

Runner melayani GET /healthz pada port health yang dikonfigurasi. Respons adalah 200 OK kapan pun proses hidup, apa pun state poll loop, jadi probe HTTP pada endpoint ini mendeteksi proses mati saja. Badan JSON menjelaskan state saat ini:
Gunakan last_poll_age_ms sebagai sinyal liveness dalam probe kustom; nilai yang tumbuh tanpa batas menunjukkan poll loop macet. Baik last_poll_at dan last_poll_age_ms adalah null sampai poll pertama selesai. /healthz milik orchestrator sendiri, pada port health-nya, selalu mengembalikan 200. Badan membawa field connected yang melaporkan apakah poll terbaru berhasil, plus spawn-queue count per-state dalam queue_counts. Untuk melihat mengapa connected bernilai false, baca field last_error tingkat atas, yang diatur ulang menjadi null oleh setiap poll yang berhasil. Gate readiness dan alerting pada connected daripada status code. Ketika SCM connector dikonfigurasi, badan /healthz orchestrator juga membawa scm_connector_connected dan objek scm_connector dengan connected, last_connected_at, last_error, reconnects, dan requests_forwarded. Kedua field adalah null ketika --scm-connector-host tidak diatur.

Metrik Prometheus

Setiap runner menyajikan metrik Prometheus di GET /metrics pada port yang sama dengan /healthz. Seri utama: Orchestrator menyajikan serinya sendiri di GET /metrics pada port yang sama dengan /healthz miliknya: Untuk autoscaling, pilih seri yang sesuai dengan gaya scaling Anda dan beri gerbang padanya sebelum diumpankan ke scaler:
  • Scaling berdasarkan kedalaman antrean: umpankan claude_code_self_hosted_orchestrator_pool_pending_sessions ke scaler HPA atau KEDA Anda, bukan queue_pending_sessions.
  • Scaling berdasarkan kapasitas: lakukan scaling berdasarkan rasio active_sessions runner terhadap capacity.
  • Gerbang pada connected: filter kueri dengan claude_code_self_hosted_orchestrator_connected == 1 per instans, sehingga nilai usang dari replika yang terputus tidak diumpankan ke scaler.
Selama gangguan poll total, ketika setiap replika terputus, kueri yang diberi gerbang tidak mengembalikan data. HPA mempertahankan jumlah replika saat ini ketika metrik tidak ada, tetapi scaler Prometheus KEDA dengan default ignoreNullValues: "true" membaca hasil kosong sebagai nol dan melakukan scale in; atur ignoreNullValues: "false" pada ScaledObject, opsional dengan batas bawah replika fallback. PodMonitor Prometheus Operator berikut mencakup kedua proses. Ini memilih pod berdasarkan label app.kubernetes.io/part-of: claude-code-self-hosted-runner dan port bernama health yang diatur oleh resep Kubernetes; sesuaikan namespace agar cocok dengan deployment Anda:

Contoh aturan peringatan

Contoh aturan peringatan ini adalah titik awal; sesuaikan ambang batasnya untuk ukuran armada Anda:

Peringatan untuk runner yang hilang dan sesi yang menunggu

Pada armada tetap, muat ClaudeRunnersBelowFloor. Dengan runner on-demand, muat ClaudeOrchestratorSessionsWaiting dan ClaudeOrchestratorQueueWaitHigh sebagai gantinya.

Peringatan ketika armada tetap kehilangan runner

ClaudeRunnersBelowFloor dipicu ketika jumlah runner yang terdaftar dan di-scrape yang tersisa lebih sedikit dari batas bawah selama 10 menit:
  • Batas bawah: atur 2 dalam expr ke sekitar setengah jumlah replika Anda, dibulatkan ke atas. Dengan tiga replika, pertahankan 2, dan peringatan dipicu ketika tersisa satu runner atau tidak ada sama sekali.
  • Namespace: ganti claude-runners di matcher dan di labels, lalu salin peringatan tersebut untuk setiap namespace tambahan. Jika target Anda tidak memiliki label namespace, hapus matcher dan label tersebut, jika tidak peringatan akan membaca 0 dan dipicu.
  • ClaudeRunnerPollStale dan ClaudeRunnerPollErrors: tetap muat keduanya dari contoh aturan peringatan, karena ClaudeRunnersBelowFloor tetap menghitung runner yang tidak dapat melakukan poll

Peringatan ketika sesi menunggu runner on-demand

ClaudeOrchestratorSessionsWaiting dipicu ketika jumlah sesi yang menunggu runner tetap di atas 0 selama 10 menit. ClaudeOrchestratorQueueWaitHigh dipicu ketika lebih dari 1% waktu tunggu antrean dalam 10 menit terakhir melebihi 160 detik, dan kondisi itu bertahan selama 5 menit:
  • Ambang batas: jika selalu ada sesi yang menunggu, naikkan > 0 dalam ClaudeOrchestratorSessionsWaiting di atas jumlah yang biasanya Anda lihat
  • ClaudeOrchestratorDisconnected: tetap muat dari contoh aturan peringatan, karena ClaudeOrchestratorSessionsWaiting berhenti dipicu sekitar 2 menit setelah orchestrator terakhir di namespace tersebut terputus

Meneruskan metrik proses anak sesi

Setiap sesi berjalan dalam proses anaknya sendiri dengan metrik OpenTelemetry-nya sendiri; pada --capacity di atas satu, runner menulis ulang cara metrik proses anak tersebut diekspos. Mengatur OTEL_METRICS_EXPORTER=prometheus pada host runner dan CLAUDE_CODE_ENABLE_TELEMETRY=1 di environment sesi, misalnya dari skrip wrapper Anda atau environment runner itu sendiri, yang diwarisi oleh sesi, akan mengekspos ulang instrumen counter dan gauge setiap proses anak pada endpoint /metrics milik runner sendiri, bersama seri runner. Runner menulis ulang exporter proses anak agar mengirim melalui OTLP ke receiver khusus loopback pada port health, menandai setiap seri dengan label session_id dan client_platform, dan menghapus seri sebuah sesi ketika sesi tersebut berakhir. Histogram tidak diteruskan, dan metrik proses anak yang namanya akan bertabrakan dengan prefiks milik runner sendiri akan dibuang. Pada --capacity 1 default, penulisan ulang ini tidak berlaku: proses anak sesi mengikat endpoint Prometheus-nya sendiri pada port 9464 seperti biasa.

Menggabungkan metrik sesi dengan metrik runner

Untuk melihat biaya yang telah dihabiskan sesi yang idle, lakukan join claude_code_self_hosted_runner_session_idle_seconds milik runner dengan metrik biaya Claude Code pada ccr_session_id. Metrik runner tidak membawa label tersebut, jadi berikan label itu dengan label_replace, seperti dalam kueri ini:
Kueri ini mengembalikan satu hasil per sesi yang idle lebih dari sepuluh menit: biaya dalam dolar AS yang telah dihitung oleh proses Claude Code sesi tersebut sejauh ini. Untuk melakukan join dengan metrik Claude Code lainnya, ganti claude_code_cost_usage_total dalam kueri. Kueri ini berfungsi pada --capacity berapa pun.
  • session_id: pada port 9464, label tersebut pada metrik Claude Code berisi session.id milik Claude Code sendiri, yang tidak cocok dengan seri runner mana pun. Join pada label itu tidak mengembalikan apa pun, jadi lakukan join pada ccr_session_id.
  • Metrik Claude Code tidak memiliki ccr_session_id: periksa bahwa OTEL_METRICS_INCLUDE_SESSION_ID tidak diatur ke false

Semantik penghitung siklus hidup sesi

Penghitung sessions_started_total, sessions_completed_total, sessions_failed_total, dan sessions_interrupted_total mengklasifikasikan setiap sesi berdasarkan cara sesi tersebut berakhir. Setiap proses anak sesi yang di-spawn menambah sessions_started_total pada saat spawn, dan tepat satu dari tiga lainnya bertambah saat keluar, sehingga sessions_started_total dikurangi jumlah tiga lainnya sama dengan jumlah proses anak sesi yang sedang berjalan.
  • completed: sesi berakhir dengan bersih. Ini mencakup proses anak yang keluar dengan sendirinya dengan kode 0, sesi yang diarsipkan atau dihapus saat proses anak masih terhubung, dan runner yang menyerahkan kembali slot dengan bersih: melepaskan sesi pada idle timeout, waktu pensiun, atau batas --kill-session-after-min; timeout startup; atau deassign dari sisi server yang diketahui loop poll sebelum proses anak keluar. Menambah sessions_completed_total.
  • failed: proses anak keluar dengan sendirinya dengan kode bukan nol, baik karena crash maupun kegagalan setup setelah spawn. Menambah sessions_failed_total.
  • interrupted: runner menghentikan proses anak karena alasan operasional yang bukan keberhasilan sesi maupun kesalahan runner, seperti drain, atau menghentikan sesi yang masih berada di runner ketika jendela tenggang SELF_HOSTED_RUNNER_MAX_LIFETIME_GRACE_MS setelah batas --kill-session-after-min-nya berakhir. Rolling restart Kubernetes yang mengirim SIGTERM adalah salah satu contoh drain. Menambah sessions_interrupted_total.
Sebelum v2.1.260, runner menghentikan setiap sesi yang mencapai batas --kill-session-after-min-nya dan menghitungnya dalam sessions_interrupted_total. CLAUDE_RUNNER_EXIT_REASON milik hook post-session mengklasifikasikan penyerahan bersih secara berbeda. Hook melaporkannya sebagai interrupted, karena runner menghentikan proses anak: pelepasan, timeout startup, deassign server, serta pengarsipan atau penghapusan yang diketahui poll terlebih dahulu. Penghitung ini mencatat peristiwa yang sama sebagai completed, karena slot diserahkan kembali dengan bersih. Jika Anda merekonsiliasi tanda terima hook langsung terhadap sessions_completed_total, Anda akan menghitung penyelesaian lebih sedikit dari yang sebenarnya. Gunakan hook untuk jaminan per sesi dan penghitung untuk laju agregat. Pada environment sekali pakai, yaitu --capacity 1 dengan --drain-grace-sec 0 default, setiap proses runner keluar sesaat setelah satu sesinya berakhir. sessions_completed_total, sessions_failed_total, dan sessions_interrupted_total hanya bertambah di akhir sesi, tepat sebelum keluar, sehingga scrape Prometheus setiap 15 hingga 60 detik jarang menangkap penambahan tersebut sebelum seri runner menghilang; ketiga penghitung akhir sesi ini adalah penghitung terminal yang dirujuk di sisa bagian ini. sessions_started_total bertambah saat spawn dan tetap terlihat selama masa hidup sesi, sehingga dapat diandalkan muncul, tetapi pada environment sekali pakai nilainya lebih mendekati “sesi yang sedang berjalan” daripada hitungan kumulatif. Gunakan seri dalam tabel ini untuk tujuan yang sesuai alih-alih penghitung terminal: Baris orchestrator_* hanya ada pada environment yang menjalankan orchestrator on-demand. Pada armada tetap yang runner-nya hidup lebih lama dari sesinya, dengan --drain-grace-sec di atas 0, gunakan sum(rate(claude_code_self_hosted_runner_sessions_started_total[5m])) untuk throughput; pada armada sekali pakai, seri tersebut memiliki masalah jendela scrape yang sama dengan penghitung terminal, jadi andalkan hitungan sesi yang diantrekan sebagai gantinya. Periksa backlog di tab Activity environment, pada halaman admin Cloud environments: runner tidak mengekspor seri kedalaman antrean. Untuk pelaporan hasil per sesi, gunakan hook post-session sebagai gantinya: hook ini dipicu di setiap akhir sesi ketika proses anak telah di-spawn, kecuali pada penghentian runner secara mendadak seperti preemption VM, sesuai kontrak hook itu sendiri.

Apa selanjutnya