Cara menjalankan runner self-hosted CircleCI di Mac
CircleCI machine runner 3 dipasang di macOS dari Homebrew tap milik CircleCI dan berjalan sebagai LaunchAgent. Buat namespace dan resource class, salin token-nya, taruh di config.yaml milik runner, lalu bootstrap layanannya. Job menjangkaunya dengan machine: true dan resource_class: namespace/name.
Yang Anda butuhkan lebih dulu
- Hak admin organisasi di CircleCI. Seorang admin harus menyetujui ketentuan runner di Org, lalu Runners, sebelum menunya muncul.
- Minimal satu kredit di akun. Menurut CircleCI, job runner tidak memakai kredit, tapi penyimpanan dan transfer jaringan bisa.
- Mac Apple silicon dengan akses admin, Homebrew, dan Xcode.
sha256sum, yang dicantumkan CircleCI sebagai prasyarat. Dapatkan denganbrew install coreutils.
1. Buat namespace dan resource class
Di aplikasi web, buka Runners dan pilih Create Resource Class. Setiap organisasi mendapat satu namespace. Jika Anda menerbitkan orb, Anda sudah punya namespace. Beri nama resource class seperti mac-mini-m6. Simpan, lalu salin token-nya. CircleCI hanya menampilkannya sekali.
CLI melakukan hal yang sama:
circleci namespace create <name> --org-id <your-organization-id> circleci runner resource-class create <namespace>/<resource-class> <description> --generate-token
2. Pasang runner dengan Homebrew
brew tap circleci-public/circleci brew trust circleci-public/circleci brew install circleci-runner
Baris tengahnya baru. Homebrew 7.0.7, versi di Mac kami pada Oktober 2026, menolak memuat package dari tap pihak ketiga sampai Anda memercayainya. Halaman CircleCI belum menampilkan langkah ini. Runner-nya datang sebagai Homebrew cask.
macOS mungkin menampilkan pemberitahuan bahwa item latar belakang dari Circle Internet Services telah ditambahkan. Itu wajar. Homebrew juga menulis plist LaunchAgent ke ~/Library/LaunchAgents/com.circleci.runner.plist.
3. Tambahkan token ke config.yaml
nano $HOME/Library/Preferences/com.circleci.runner/config.yaml
runner: name: "mac-mini-m6" working_directory: "/Users/$USER/Library/com.circleci.runner/workdir" cleanup_working_directory: true api: auth_token: "your-resource-class-token"
Dengan cleanup_working_directory aktif, setiap job mulai dari checkout yang bersih. Secara default DerivedData Xcode ada di ~/Library/Developer/Xcode/DerivedData, jadi cache build tetap bertahan. Jika Anda memakai -derivedDataPath di dalam working directory, proses pembersihan menghapusnya setelah setiap job.
Lindungi token-nya
Token resource class adalah yang membuat sebuah mesin bisa mengambil job untuk class itu. Siapa pun yang membacanya bisa memasang mesinnya sendiri dan menerima job Anda, lengkap dengan secret Anda. Kunci file config hanya untuk pengguna Anda, dan ganti token jika pernah bocor.
chmod 600 $HOME/Library/Preferences/com.circleci.runner/config.yaml ls -l $HOME/Library/Preferences/com.circleci.runner/config.yaml
Logika yang sama berlaku untuk job. Job berjalan sebagai pengguna macOS yang menyalakan runner, di disk yang sama dengan semua hal lain. Arahkan hanya proyek tepercaya ke resource class ini.
4. Terima notarisasinya
Binary-nya berasal dari internet, jadi macOS harus menyetujuinya. CircleCI mendokumentasikan pengecekan tanda tangan lebih dulu, lalu penghapusan flag karantina.
spctl -a -vvv -t install "$(brew --prefix)/bin/circleci-runner" sudo xattr -r -d com.apple.quarantine "$(brew --prefix)/bin/circleci-runner"
Perintah pertama seharusnya menampilkan accepted, dengan source Notarized Developer ID.
5. Jalankan runner di GUI domain
Jalankan perintah ini dari Terminal di desktop Mac. GUI domain adalah sesi desktop yang sedang login. Di sanalah Simulator dan login keychain berada.
launchctl bootstrap gui/$(id -u) $HOME/Library/LaunchAgents/com.circleci.runner.plist launchctl enable gui/$(id -u)/com.circleci.runner launchctl kickstart -k gui/$(id -u)/com.circleci.runner launchctl print gui/$(id -u)/com.circleci.runner
CircleCI juga mendokumentasikan opsi user domain untuk sesi headless. Opsi itu memindahkan plist ke /Library/LaunchAgents. Di macOS 27, kami melihat plist di folder itu merusak login otomatis di setiap boot. Lihat login otomatis di Mac headless. Untuk pekerjaan iOS, kami menyarankan GUI domain dengan login otomatis.
6. Pastikan bertahan setelah reboot
Plist di ~/Library/LaunchAgents dimuat saat penggunanya login. Nyalakan login otomatis untuk akun ini di System Settings, bagian Users and Groups. Matikan sleep dengan sudo pmset -a sleep 0. Reboot sekali dan cek launchctl print lagi. Log ada di ~/Library/Logs/com.circleci.runner/runner.log.
7. Arahkan job ke Mac
version: 2.1
jobs:
ios-tests:
machine: true
resource_class: your-namespace/mac-mini-m6
steps:
- checkout
- run:
name: Run tests
command: |
rm -rf build/TestResults.xcresult
xcodebuild test -project MyApp.xcodeproj -scheme MyApp -destination 'platform=iOS Simulator,name=iPhone 17,OS=26.5' -resultBundlePath build/TestResults.xcresult
- run:
name: Zip result bundle
when: always
command: ditto -c -k --keepParent build/TestResults.xcresult TestResults.xcresult.zip
- store_artifacts:
path: TestResults.xcresult.zip
workflows:
ios:
jobs:
- ios-testsDokumentasi CircleCI menyebut dua field yang wajib ada di job runner: machine: true dan resource_class. Tidak ada key macos: xcode: di sini, karena Anda tidak memilih image. Job memakai versi Xcode apa pun yang dipilih di Mac. Di Mac MacRun, itu Xcode 26.6 dengan runtime simulator iOS 26.5.
Error umum dan cara memperbaikinya
Refusing to load cask ... from untrusted tap. Jalankanbrew trust circleci-public/circleci, lalu pasang lagi.- macOS memblokir binary-nya. Anda melewatkan langkah notarisasi. Jalankan perintah
xattrdi atas. - Job masuk antrean tapi tidak pernah mulai. Cek apakah resource class di config.yml sama dengan yang Anda buat, lalu baca
runner.log. - Docker layer caching tidak berjalan. CircleCI mencantumkannya sebagai fitur yang tidak didukung di runner self-hosted.
xcodebuild: error: Existing file at -resultBundlePath. Hapus bundle lama sebelum step test. Kami mengalami ini di Xcode 26.6.
Untuk menghentikan runner, pakai launchctl bootout gui/$(id -u)/com.circleci.runner. Untuk menghapusnya, jalankan brew uninstall --cask circleci-public/homebrew-circleci/circleci-runner.
Mengapa Mac khusus membantu
Keuntungan utamanya adalah cache yang hangat. Dalam benchmark kami, kami mem-build aplikasi iOS Wikipedia dengan Xcode 26.6. Job biasa setelah perubahan kecil butuh 27 detik di M6 yang hangat. Di runner macos-26 baru yang di-hosting GitHub, butuh 269 detik. Clean build butuh 86 detik, dibanding 183 detik.
Kapan macOS hosted dari CircleCI sudah cukup
CircleCI menjalankan executor Mac miliknya sendiri. Dokumentasinya, yang kami baca pada Oktober 2026, mencantumkan m4pro.medium dengan 6 vCPU dan 28 GB, serta m4pro.large dengan 12 vCPU dan 56 GB. Keduanya punya memori lebih besar dari M6 16 GB kami. Jika test suite Anda butuh memori sebanyak itu, atau Anda build beberapa kali seminggu, tetaplah di hosted. Lewati juga MacRun jika Anda butuh SLA, IP statis, atau beberapa region.
Lihat sistem CI lain untuk setup di sisi MacRun, atau bandingkan biaya dengan jumlah menit Anda sendiri.
Pertanyaan yang sering diajukan
Apakah runner self-hosted CircleCI gratis?
+
Menurut CircleCI, eksekusi di runner tidak memakai kredit. Anda tetap butuh minimal satu kredit di akun, karena penyimpanan dan transfer jaringan masih bisa ditagih.
Di mana config runner CircleCI di macOS?
+
Di $HOME/Library/Preferences/com.circleci.runner/config.yaml. Log masuk ke $HOME/Library/Logs/com.circleci.runner/runner.log.
Sebaiknya saya memakai GUI domain atau user domain?
+
Untuk build iOS, GUI domain dengan login otomatis. Runner berjalan di dalam sesi desktop yang dibutuhkan Simulator dan login keychain.
Apakah Docker layer caching berjalan di runner self-hosted CircleCI?
+
Tidak. CircleCI mencantumkan Docker layer caching sebagai fitur yang tidak didukung di runner self-hosted.