Como rodar um runner auto-hospedado do CircleCI em um Mac
O machine runner 3 do CircleCI é instalado no macOS pelo tap do Homebrew do CircleCI e roda como LaunchAgent. Crie um namespace e uma resource class, copie o token, coloque no config.yaml do runner e faça o bootstrap do serviço. Os jobs chegam até ele com machine: true e resource_class: namespace/name.
O que você precisa antes
- Permissão de administrador da organização no CircleCI. Um administrador precisa aceitar os termos do runner em Org, depois Runners, antes de o menu aparecer.
- Pelo menos um crédito na conta. O CircleCI diz que jobs de runner não usam créditos, mas armazenamento e transferência de rede podem usar.
- Um Mac com Apple silicon, acesso de administrador, Homebrew e Xcode.
sha256sum, que o CircleCI lista como pré-requisito. Instale combrew install coreutils.
1. Crie um namespace e uma resource class
No app web, abra Runners e selecione Create Resource Class. Cada organização tem um namespace. Se você publica orbs, já tem um. Dê à resource class um nome como mac-mini-m6. Salve e copie o token. O CircleCI mostra o token uma única vez.
A CLI faz a mesma coisa:
circleci namespace create <name> --org-id <your-organization-id> circleci runner resource-class create <namespace>/<resource-class> <description> --generate-token
2. Instale o runner com Homebrew
brew tap circleci-public/circleci brew trust circleci-public/circleci brew install circleci-runner
A linha do meio é nova. O Homebrew 7.0.7, a versão no nosso Mac em outubro de 2026, se recusa a carregar pacotes de um tap de terceiros até você confiar nele. A página do CircleCI ainda não mostra esse passo. O runner chega como um cask do Homebrew.
O macOS pode mostrar um aviso de que um item em segundo plano da Circle Internet Services foi adicionado. Isso é esperado. O Homebrew também grava o plist do LaunchAgent em ~/Library/LaunchAgents/com.circleci.runner.plist.
3. Adicione o token ao 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"
Com cleanup_working_directory ligado, cada job começa de um checkout limpo. O DerivedData do Xcode fica em ~/Library/Developer/Xcode/DerivedData por padrão, então os caches de build continuam lá. Se você passar -derivedDataPath dentro do diretório de trabalho, a limpeza apaga tudo depois de cada job.
Proteja o token
O token da resource class é o que permite a uma máquina pegar jobs dessa classe. Quem ler o token pode ligar a própria máquina e receber os seus jobs, com os seus segredos. Restrinja o arquivo de configuração ao seu usuário e troque o token se ele vazar.
chmod 600 $HOME/Library/Preferences/com.circleci.runner/config.yaml ls -l $HOME/Library/Preferences/com.circleci.runner/config.yaml
A mesma lógica vale para os jobs. Eles rodam com o usuário do macOS que iniciou o runner, no mesmo disco de todo o resto. Aponte para esta resource class só projetos confiáveis.
4. Aceite a notarização
O binário vem da internet, então o macOS precisa aprovar. O CircleCI documenta conferir a assinatura primeiro e depois remover a marca de quarentena.
spctl -a -vvv -t install "$(brew --prefix)/bin/circleci-runner" sudo xattr -r -d com.apple.quarantine "$(brew --prefix)/bin/circleci-runner"
O primeiro comando deve dizer accepted, com source Notarized Developer ID.
5. Inicie o runner no domínio GUI
Rode estes comandos no Terminal na área de trabalho do Mac. O domínio GUI é a sessão de área de trabalho com login feito. É lá que ficam o Simulador e o keychain de login.
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
O CircleCI também documenta uma opção de domínio de usuário para sessões sem interface. Ela move o plist para /Library/LaunchAgents. No macOS 27 vimos um plist nessa pasta quebrar o login automático em toda inicialização. Veja login automático em um Mac sem monitor. Para trabalho com iOS, sugerimos o domínio GUI com login automático.
6. Faça ele sobreviver a uma reinicialização
Um plist em ~/Library/LaunchAgents carrega quando o usuário entra. Ative o login automático para esta conta em System Settings, em Users and Groups. Desligue o repouso com sudo pmset -a sleep 0. Reinicialize uma vez e confira o launchctl print de novo. Os logs ficam em ~/Library/Logs/com.circleci.runner/runner.log.
7. Aponte um job para o 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-testsA documentação do CircleCI cita dois campos que um job de runner precisa ter: machine: true e a resource_class. Não existe a chave macos: xcode: aqui, porque você não escolhe uma imagem. O job usa o Xcode que estiver selecionado no Mac. Em um Mac da MacRun é o Xcode 27.1 com o runtime do simulador iOS 27.1.
Erros comuns e soluções
Refusing to load cask ... from untrusted tap. Rodebrew trust circleci-public/circlecie instale de novo.- O macOS bloqueia o binário. Você pulou o passo da notarização. Rode o comando
xattracima. - Os jobs entram na fila mas nunca começam. Confira se a resource class no config.yml é a mesma que você criou e leia o
runner.log. - O cache de camadas do Docker não funciona. O CircleCI diz que ele não é suportado em runners auto-hospedados.
xcodebuild: error: Existing file at -resultBundlePath. Apague o bundle antigo antes da etapa de teste. Vimos isso no Xcode 26.6.
Para parar o runner, use launchctl bootout gui/$(id -u)/com.circleci.runner. Para removê-lo, rode brew uninstall --cask circleci-public/homebrew-circleci/circleci-runner.
Por que um Mac dedicado ajuda
Os caches aquecidos são o maior ganho. No nosso benchmark fizemos o build do app iOS da Wikipedia com o Xcode 26.6. Um job típico depois de uma pequena mudança levou 27 segundos em um M6 aquecido. Ele levou 269 segundos em um runner macos-26 novo hospedado pelo GitHub. Um build limpo levou 86 segundos contra 183.
Quando o macOS hospedado do CircleCI basta
O CircleCI tem seus próprios executors Mac. A documentação, lida em outubro de 2026, lista o m4pro.medium com 6 vCPUs e 28 GB, e o m4pro.large com 12 vCPUs e 56 GB. Os dois têm mais memória que o nosso M6 de 16 GB. Se a sua suíte precisa de tanta memória, ou se você faz builds poucas vezes por semana, fique no hospedado. Também não escolha a MacRun se você precisa de um SLA, de um IP fixo ou de várias regiões.
Veja outros sistemas de CI para o lado da MacRun na configuração, ou compare os custos com os seus próprios minutos.
Perguntas frequentes
O runner auto-hospedado do CircleCI é gratuito?
+
O CircleCI diz que a execução no runner não usa créditos. Você precisa de pelo menos um crédito na conta, porque armazenamento e transferência de rede ainda podem ser cobrados.
Onde fica a configuração do runner do CircleCI no macOS?
+
Em $HOME/Library/Preferences/com.circleci.runner/config.yaml. Os logs vão para $HOME/Library/Logs/com.circleci.runner/runner.log.
Devo usar o domínio GUI ou o domínio de usuário?
+
Para builds de iOS, o domínio GUI com login automático. Ele roda dentro da sessão de área de trabalho que o Simulador e o keychain de login precisam.
O cache de camadas do Docker funciona em um runner auto-hospedado do CircleCI?
+
Não. O CircleCI diz que o cache de camadas do Docker não é suportado em runners auto-hospedados.