1. Perché usare un runner CircleCI self-hosted su Mac?
CircleCI offre ambienti di esecuzione macOS basati sul cloud, ma comportano costi e limitazioni significativi. Le risorse macOS su CircleCI usano un sistema basato su crediti in cui ogni minuto su un executor macOS consuma 50-100 crediti a seconda della resource class. Per i team che eseguono build iOS frequenti, questo può rapidamente arrivare a $300-$500 al mese o più.
Un runner self-hosted su un Mac Mini M4 dedicato di MyRemoteMac elimina del tutto la fatturazione al minuto. Ottieni una macchina Apple Silicon dedicata con archiviazione persistente, cache calde e accesso root completo per una tariffa mensile fissa a partire da $85/mese. Ecco un confronto dettagliato:
| Caratteristica | CircleCI Cloud macOS | MyRemoteMac self-hosted |
|---|---|---|
| Modello di costo | 50-100 crediti/min (~$0,06-$0,12/min) | $85/mese fisso (minuti illimitati) |
| Architettura | Intel x86 o M1 (condiviso) | Apple M4 (dedicato, ultima generazione) |
| Velocità di build | ~14 min (progetto iOS medio) | ~5 min (stesso progetto) |
| Persistenza della cache | Effimera (da ripristinare a ogni job) | Persistente su disco (istantanea) |
| Tempo di attesa in coda | 30s - 5min (varia in base al piano) | 0s (hardware dedicato) |
| Privacy / controllo dei dati | Infrastruttura condivisa | Macchina dedicata, controllo totale |
| Software personalizzato | Solo immagine preinstallata | Accesso root completo, qualsiasi software |
Vantaggio chiave: con un runner self-hosted persistente, DerivedData, le cache di Swift Package Manager e CocoaPods vengono conservati tra una build e l'altra. Questo da solo può ridurre i tempi di build del 50-70% rispetto agli ambienti macOS cloud effimeri di CircleCI, che ripartono da zero ogni volta. Combinato con le prestazioni single-thread superiori del chip M4, le tue build iOS saranno notevolmente più veloci.
2. Prerequisiti
Prima di iniziare, assicurati di avere quanto segue:
- Un Mac Mini M4 server di MyRemoteMac (a partire da $85/mese)
- Un account CircleCI con un piano Performance, Scale o Server (i runner self-hosted richiedono un piano a pagamento)
- Accesso SSH al tuo Mac Mini (fornito con il tuo abbonamento MyRemoteMac)
- Un account Apple Developer (per il code signing e i provisioning profile)
- Familiarità di base con YAML, la configurazione di CircleCI e i comandi da terminale
3. Passaggio 1: accedi via SSH al tuo Mac Mini e installa le dipendenze
Innanzitutto, collegati al tuo Mac Mini M4 via SSH. Avrai ricevuto le tue credenziali quando hai configurato il tuo server MyRemoteMac. Dobbiamo installare Xcode e gli strumenti richiesti per le build iOS prima di configurare il runner CircleCI.
Collegati via SSH
# Connect to your Mac Mini M4
ssh admin@your-server-ip
# Verify you're on Apple Silicon
uname -m
# Expected output: arm64
# Check macOS version
sw_vers
# ProductName: macOS
# ProductVersion: 15.2
# BuildVersion: 24C101
Installa Homebrew e gli Xcode Command Line Tools
# Install Homebrew (if not already installed)
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
# Add Homebrew to PATH
echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> ~/.zprofile
eval "$(/opt/homebrew/bin/brew shellenv)"
# Install Xcode Command Line Tools
xcode-select --install
# Accept the license agreement
sudo xcodebuild -license accept
Installa Xcode (versione completa)
Per le build iOS ti serve l'applicazione Xcode completa. Il modo più veloce per installarla su un server senza interfaccia grafica è usare xcodes:
# Install xcodes CLI tool
brew install xcodes
# List available Xcode versions
xcodes list
# Install the latest stable Xcode
xcodes install 16.2
# Set it as the active Xcode
sudo xcode-select -s /Applications/Xcode-16.2.app/Contents/Developer
# Verify installation
xcodebuild -version
# Xcode 16.2
# Build version 16C5032a
Installa i simulatori iOS e gli strumenti di build
# Install the iOS 18 simulator runtime
xcodebuild -downloadPlatform iOS
# Verify simulator availability
xcrun simctl list runtimes
# == Runtimes ==
# iOS 18.2 (18.2 - 22C150) - com.apple.CoreSimulator.SimRuntime.iOS-18-2
# Install additional build tools
brew install xcbeautify fastlane swiftlint
4. Passaggio 2: installa il runner agent di CircleCI
CircleCI usa un machine runner agent per collegare il tuo Mac Mini alla piattaforma CircleCI. Il machine runner riceve i job da CircleCI e li esegue direttamente sul tuo host macOS. Questo è diverso dal container runner (che funziona solo su Linux).
Crea un utente dedicato per il runner
Si consiglia di creare un utente dedicato per eseguire l'agent CircleCI ai fini dell'isolamento di sicurezza:
# Create a circleci user (optional but recommended)
sudo dscl . -create /Users/circleci
sudo dscl . -create /Users/circleci UserShell /bin/zsh
sudo dscl . -create /Users/circleci RealName "CircleCI Runner"
sudo dscl . -create /Users/circleci UniqueID 550
sudo dscl . -create /Users/circleci PrimaryGroupID 20
sudo dscl . -create /Users/circleci NFSHomeDirectory /Users/circleci
sudo mkdir -p /Users/circleci
sudo chown circleci:staff /Users/circleci
# Or simply use your existing admin user (simpler setup)
Scarica e installa il runner agent
# Create a directory for the runner
sudo mkdir -p /opt/circleci
# Download the latest CircleCI machine runner for macOS ARM64
# Check https://circleci.com/docs/runner-installation-mac/ for latest version
curl -o /tmp/circleci-runner.pkg \
https://circleci-binary-releases.s3.amazonaws.com/circleci-runner/1.0/circleci-runner_darwin_arm64.pkg
# Install the runner package
sudo installer -pkg /tmp/circleci-runner.pkg -target /
# Verify the installation
circleci-runner --version
Configura il runner agent
Crea il file di configurazione del runner. Ti servirà il tuo token di autenticazione del runner dalla dashboard di CircleCI (trattato nel Passaggio 3). Per ora, crea la struttura del file di configurazione:
# Create the configuration directory
sudo mkdir -p /opt/circleci/config
# Create the runner configuration file
sudo tee /opt/circleci/config/runner-agent-config.yaml << 'EOF'
api:
auth_token: YOUR_RUNNER_TOKEN_HERE
runner:
name: mac-mini-m4-runner
working_directory: /opt/circleci/workdir
cleanup_working_directory: true
max_run_time: 5h
# Optional: limit concurrent tasks
# command_prefix: ["nice", "-n", "10"]
logging:
file: /opt/circleci/logs/runner.log
EOF
# Create required directories
sudo mkdir -p /opt/circleci/workdir
sudo mkdir -p /opt/circleci/logs
# Set permissions (adjust user if using dedicated circleci user)
sudo chown -R admin:staff /opt/circleci
Crea un launch agent macOS per la persistenza
Per garantire che il runner si avvii automaticamente all'accensione e si riavvii in caso di crash, crea un LaunchDaemon macOS:
# Create the LaunchDaemon plist
sudo tee /Library/LaunchDaemons/com.circleci.runner.plist << 'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.circleci.runner</string>
<key>ProgramArguments</key>
<array>
<string>/opt/circleci/circleci-runner</string>
<string>machine</string>
<string>--config</string>
<string>/opt/circleci/config/runner-agent-config.yaml</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>StandardOutPath</key>
<string>/opt/circleci/logs/runner-stdout.log</string>
<key>StandardErrorPath</key>
<string>/opt/circleci/logs/runner-stderr.log</string>
<key>EnvironmentVariables</key>
<dict>
<key>PATH</key>
<string>/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
</dict>
</dict>
</plist>
EOF
# Load and start the service
sudo launchctl load /Library/LaunchDaemons/com.circleci.runner.plist
# Verify the service is running
sudo launchctl list | grep circleci
# Expected: PID listed with com.circleci.runner
# Check the logs
tail -f /opt/circleci/logs/runner.log
Importante: il runner agent non si connetterà finché non aggiungi un token di autenticazione valido. Completa prima il Passaggio 3 per generare il token, poi aggiorna il file runner-agent-config.yaml con il token reale e riavvia il servizio.
5. Passaggio 3: configura il runner nella dashboard di CircleCI
Ora devi registrare il tuo runner nell'interfaccia web di CircleCI e generare un token di autenticazione. Questo collega il tuo Mac Mini alla tua organizzazione CircleCI.
Crea una resource class
In CircleCI, i runner self-hosted sono organizzati per resource class. Una resource class è un'etichetta che mappa il tuo .circleci/config.yml a un insieme specifico di runner.
- Vai su CircleCI Dashboard → Organization Settings → Self-Hosted Runners
- Clicca su "Create Resource Class"
- Imposta il Namespace sul nome della tua organizzazione (ad es.
your-org) - Imposta il nome della Resource Class su qualcosa di descrittivo (ad es.
mac-runner) - Questo crea un identificatore di resource class:
your-org/mac-runner
Genera un token di autenticazione del runner
- Dopo aver creato la resource class, clicca su "Create New Token"
- Assegna al token un nome descrittivo (ad es.
mac-mini-m4-token) - Copia immediatamente il token generato — verrà mostrato una sola volta
Aggiorna la configurazione del runner con il tuo token
# SSH back into your Mac Mini
ssh admin@your-server-ip
# Update the runner configuration with your real token
sudo nano /opt/circleci/config/runner-agent-config.yaml
# Replace YOUR_RUNNER_TOKEN_HERE with the actual token:
# api:
# auth_token: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...
# Restart the runner service to apply the new token
sudo launchctl unload /Library/LaunchDaemons/com.circleci.runner.plist
sudo launchctl load /Library/LaunchDaemons/com.circleci.runner.plist
# Verify the runner connects successfully
tail -20 /opt/circleci/logs/runner.log
# Look for: "Runner is ready to receive jobs"
Una volta connesso, il runner dovrebbe apparire come "Online" nella dashboard di CircleCI sotto Self-Hosted Runners. Se non appare entro 60 secondi, controlla il file di log per eventuali messaggi di errore.
Usare la CLI di CircleCI (alternativa)
Puoi anche gestire i runner tramite la CLI di CircleCI:
# Install the CircleCI CLI
brew install circleci
# Authenticate with CircleCI
circleci setup
# Create a resource class via CLI
circleci runner resource-class create your-org/mac-runner \
"Mac Mini M4 Runner" --generate-token
# List your runners
circleci runner instance list your-org/mac-runner
6. Passaggio 4: crea il tuo .circleci/config.yml per le build iOS
Crea un file .circleci/config.yml nella radice del tuo repository. La differenza fondamentale rispetto a una configurazione CircleCI standard è l'uso di machine: true con la tua resource_class personalizzata per puntare al tuo runner self-hosted.
version: 2.1
jobs:
build-and-test:
machine: true
resource_class: your-org/mac-runner
environment:
SCHEME: "MyApp"
DESTINATION: "platform=iOS Simulator,name=iPhone 16 Pro,OS=18.2"
DERIVED_DATA_PATH: "DerivedData"
SPM_CACHE_PATH: ".spm-cache"
steps:
- checkout
- run:
name: Select Xcode version
command: |
sudo xcode-select -s /Applications/Xcode-16.2.app/Contents/Developer
xcodebuild -version
- run:
name: Resolve Swift Package Dependencies
command: |
xcodebuild -resolvePackageDependencies \
-scheme "$SCHEME" \
-clonedSourcePackagesDirPath "$SPM_CACHE_PATH"
- run:
name: Build the app
command: |
xcodebuild build \
-scheme "$SCHEME" \
-destination "$DESTINATION" \
-clonedSourcePackagesDirPath "$SPM_CACHE_PATH" \
-derivedDataPath "$DERIVED_DATA_PATH" \
| xcbeautify
- run:
name: Run unit tests
command: |
xcodebuild test \
-scheme "$SCHEME" \
-destination "$DESTINATION" \
-clonedSourcePackagesDirPath "$SPM_CACHE_PATH" \
-derivedDataPath "$DERIVED_DATA_PATH" \
-resultBundlePath TestResults.xcresult \
| xcbeautify
- store_test_results:
path: TestResults.xcresult
- store_artifacts:
path: TestResults.xcresult
destination: test-results
workflows:
ios-pipeline:
jobs:
- build-and-test:
filters:
branches:
only:
- main
- develop
Nota: il valore resource_class: your-org/mac-runner deve corrispondere esattamente alla resource class che hai creato nella dashboard di CircleCI. Se non corrisponde, i job rimarranno in coda a tempo indeterminato.
7. Passaggio 5: ottimizza con caching e parallelismo
Uno dei maggiori vantaggi di un runner self-hosted è il caching persistente. Poiché il filesystem del runner è persistente, non devi caricare e scaricare le cache come fai con le risorse cloud di CircleCI. Tuttavia, ci sono ottimizzazioni aggiuntive per massimizzare la velocità delle build.
Sfrutta i DerivedData persistenti
Poiché il disco del runner persiste tra una build e l'altra, i DerivedData sono già memorizzati in cache automaticamente. Usa un percorso coerente:
# In your config.yml steps, always use a consistent DerivedData path:
- run:
name: Build with persistent cache
command: |
xcodebuild build \
-scheme "$SCHEME" \
-destination "$DESTINATION" \
-derivedDataPath ~/DerivedData/"$SCHEME" \
-clonedSourcePackagesDirPath ~/spm-cache \
| xcbeautify
# Periodically clean old DerivedData on the runner (cron job):
# 0 3 * * 0 find ~/DerivedData -maxdepth 1 -mtime +7 -exec rm -rf {} +
Persistenza del workspace tra i job
Usa i workspace di CircleCI per passare gli artefatti tra i job nello stesso workflow:
jobs:
build:
machine: true
resource_class: your-org/mac-runner
steps:
- checkout
- run:
name: Build
command: |
xcodebuild build \
-scheme "MyApp" \
-destination "generic/platform=iOS" \
-derivedDataPath DerivedData
- persist_to_workspace:
root: .
paths:
- DerivedData
test:
machine: true
resource_class: your-org/mac-runner
steps:
- checkout
- attach_workspace:
at: .
- run:
name: Run tests
command: |
xcodebuild test \
-scheme "MyApp" \
-destination "platform=iOS Simulator,name=iPhone 16 Pro,OS=18.2" \
-derivedDataPath DerivedData \
| xcbeautify
workflows:
build-test:
jobs:
- build
- test:
requires:
- build
Esecuzione parallela dei test
- run:
name: Run tests in parallel
command: |
xcodebuild test \
-scheme "MyApp" \
-destination "platform=iOS Simulator,name=iPhone 16 Pro,OS=18.2" \
-destination "platform=iOS Simulator,name=iPhone 15,OS=17.5" \
-parallel-testing-enabled YES \
-maximum-parallel-testing-workers 4 \
-derivedDataPath DerivedData \
| xcbeautify
Test splitting di CircleCI
Per suite di test di grandi dimensioni, usa il test splitting integrato di CircleCI per distribuire i test tra runner paralleli:
jobs:
test:
machine: true
resource_class: your-org/mac-runner
parallelism: 3
steps:
- checkout
- run:
name: Split and run tests
command: |
# Generate test plan
TESTS=$(circleci tests glob "**/*Tests.swift" | \
circleci tests split --split-by=timings)
# Run only this container's portion of tests
xcodebuild test \
-scheme "MyApp" \
-destination "platform=iOS Simulator,name=iPhone 16 Pro,OS=18.2" \
-only-testing:$TESTS \
| xcbeautify
8. Esempi di workflow
Ecco esempi di workflow completi e pronti per la produzione per scenari CI/CD iOS comuni.
Pipeline completa di build, test e deploy iOS
version: 2.1
jobs:
lint:
machine: true
resource_class: your-org/mac-runner
steps:
- checkout
- run:
name: Run SwiftLint
command: swiftlint lint --reporter json > swiftlint-results.json || true
- store_artifacts:
path: swiftlint-results.json
build-and-test:
machine: true
resource_class: your-org/mac-runner
steps:
- checkout
- run:
name: Select Xcode
command: sudo xcode-select -s /Applications/Xcode-16.2.app/Contents/Developer
- run:
name: Resolve dependencies
command: |
xcodebuild -resolvePackageDependencies \
-scheme "MyApp" \
-clonedSourcePackagesDirPath ~/spm-cache
- run:
name: Build and test
command: |
xcodebuild test \
-scheme "MyApp" \
-destination "platform=iOS Simulator,name=iPhone 16 Pro,OS=18.2" \
-clonedSourcePackagesDirPath ~/spm-cache \
-derivedDataPath ~/DerivedData/MyApp \
-resultBundlePath TestResults.xcresult \
-parallel-testing-enabled YES \
| xcbeautify
- store_test_results:
path: TestResults.xcresult
- store_artifacts:
path: TestResults.xcresult
deploy-testflight:
machine: true
resource_class: your-org/mac-runner
steps:
- checkout
- run:
name: Select Xcode
command: sudo xcode-select -s /Applications/Xcode-16.2.app/Contents/Developer
- run:
name: Install certificates with Fastlane Match
command: |
fastlane match appstore --readonly
- run:
name: Build and upload to TestFlight
command: |
fastlane beta
environment:
FASTLANE_USER: ${APPLE_ID}
MATCH_PASSWORD: ${MATCH_PASSWORD}
workflows:
ios-pipeline:
jobs:
- lint
- build-and-test:
requires:
- lint
- deploy-testflight:
requires:
- build-and-test
filters:
branches:
only: main
Esempio di integrazione con Fastlane
Se usi Fastlane per l'automazione delle tue build, ecco come integrarlo con il tuo runner self-hosted CircleCI:
# Fastfile (fastlane/Fastfile)
default_platform(:ios)
platform :ios do
desc "Run tests"
lane :test do
scan(
scheme: "MyApp",
device: "iPhone 16 Pro",
derived_data_path: "~/DerivedData/MyApp",
result_bundle: true,
output_directory: "./test_output"
)
end
desc "Build and push to TestFlight"
lane :beta do
match(type: "appstore", readonly: true)
increment_build_number(
build_number: ENV["CIRCLE_BUILD_NUM"]
)
gym(
scheme: "MyApp",
export_method: "app-store",
derived_data_path: "~/DerivedData/MyApp"
)
pilot(skip_waiting_for_build_processing: true)
end
end
# .circleci/config.yml using Fastlane
version: 2.1
jobs:
fastlane-test:
machine: true
resource_class: your-org/mac-runner
steps:
- checkout
- run:
name: Install dependencies
command: bundle install
- run:
name: Run Fastlane tests
command: bundle exec fastlane test
- store_test_results:
path: ./test_output
- store_artifacts:
path: ./test_output
fastlane-deploy:
machine: true
resource_class: your-org/mac-runner
steps:
- checkout
- run:
name: Install dependencies
command: bundle install
- run:
name: Deploy to TestFlight
command: bundle exec fastlane beta
workflows:
ios-workflow:
jobs:
- fastlane-test
- fastlane-deploy:
requires:
- fastlane-test
filters:
branches:
only: main
9. Confronto delle prestazioni
Ecco un confronto dettagliato di prestazioni e costi tra le risorse macOS cloud di CircleCI e un Mac Mini M4 self-hosted di MyRemoteMac:
Benchmark dei tempi di build
| Scenario | CircleCI Cloud macOS | Mac Mini M4 self-hosted | Miglioramento |
|---|---|---|---|
| Clean build (app media) | 14 min | 5 min | 2,8 volte più veloce |
| Build incrementale | 14 min (senza cache) | 1,5 min | 9,3 volte più veloce |
| Risoluzione delle dipendenze SPM | 3-5 min (download ogni volta) | 5 sec (in cache su disco) | ~60 volte più veloce |
| Suite di unit test (500 test) | 8 min | 2,5 min | 3,2 volte più veloce |
| Tempo di attesa in coda | 30s - 5 min | 0 sec | Istantaneo |
Analisi dei costi mensili
| Dimensione del team | Build/mese | Costo CircleCI Cloud | Costo MyRemoteMac | Risparmio mensile |
|---|---|---|---|---|
| Sviluppatore singolo | 100 build (10 min in media) | $100/mese | $85/mese | $25/mese |
| Team piccolo (5) | 500 build (10 min in media) | $500/mese | $85/mese | $425/mese |
| Team medio (15) | 1500 build (10 min in media) | $1.500/mese | $229/mese (M4 Pro) | $1.271/mese |
| Enterprise (50+) | 5000+ build | $5.000+/mese | $458/mese (2x M4 Pro) | $4.542+/mese |
In sintesi: per qualsiasi team che esegue più di ~75 build al mese, un Mac Mini M4 self-hosted si ripaga immediatamente. Il risparmio sui costi si amplifica ulteriormente perché le build sono più veloci su hardware dedicato con cache calde, il che significa che ogni build consuma meno minuti in partenza.
10. Risoluzione dei problemi comuni
Il runner si disconnette o appare "Offline"
Il runner agent può perdere la connessione a causa di problemi di rete o di un processo in crash. Il LaunchDaemon dovrebbe riavviarsi automaticamente, ma in caso contrario:
# Check if the process is running
ps aux | grep circleci-runner
# Check the LaunchDaemon status
sudo launchctl list | grep circleci
# View the error logs
tail -50 /opt/circleci/logs/runner-stderr.log
tail -50 /opt/circleci/logs/runner.log
# Restart the service
sudo launchctl unload /Library/LaunchDaemons/com.circleci.runner.plist
sudo launchctl load /Library/LaunchDaemons/com.circleci.runner.plist
# If the token expired, generate a new one in CircleCI dashboard
# and update /opt/circleci/config/runner-agent-config.yaml
resource_class non trovata o job bloccati in coda
Se i job restano in coda con "No matching runner found", la resource class nella tua configurazione non corrisponde a quella della dashboard:
# Verify the exact resource class name in CircleCI dashboard:
# Organization Settings > Self-Hosted Runners > Resource Classes
# The resource_class in .circleci/config.yml must match exactly:
# resource_class: your-org/mac-runner (case-sensitive!)
# Check your runner is online:
circleci runner instance list your-org/mac-runner
# Common mistakes:
# - Wrong namespace (org name vs personal namespace)
# - Typo in resource class name
# - Runner is offline or token is invalid
# - Using 'docker' executor instead of 'machine: true'
Errori di code signing di Xcode
Il code signing su una macchina CI richiede un'attenta gestione del keychain. Il processo del runner potrebbe non avere accesso al keychain di login:
# Option 1: Use Fastlane Match (recommended)
# In your Fastfile:
match(type: "appstore", readonly: true)
# Option 2: Manual keychain management in your job steps
- run:
name: Setup code signing
command: |
# Decode and import the certificate
echo "$BUILD_CERTIFICATE_BASE64" | base64 --decode > /tmp/cert.p12
# Create a temporary keychain
security create-keychain -p "ci" /tmp/ci.keychain
security set-keychain-settings -lut 21600 /tmp/ci.keychain
security unlock-keychain -p "ci" /tmp/ci.keychain
# Import the certificate
security import /tmp/cert.p12 -P "$P12_PASSWORD" \
-A -t cert -f pkcs12 -k /tmp/ci.keychain
security list-keychain -d user -s /tmp/ci.keychain
# Install provisioning profile
mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
echo "$PROVISIONING_PROFILE_BASE64" | base64 --decode \
> ~/Library/MobileDevice/Provisioning\ Profiles/profile.mobileprovision
Il simulatore non si avvia o va in timeout
I simulatori possono entrare in uno stato errato sulle macchine CI a lunga esecuzione. Resettali tra una build e l'altra:
# Add a pre-build step to clean simulators
- run:
name: Reset simulators
command: |
xcrun simctl shutdown all 2>/dev/null || true
xcrun simctl erase all 2>/dev/null || true
# If a specific runtime is missing, reinstall it:
xcodebuild -downloadPlatform iOS
# List available simulators
xcrun simctl list devices available
Spazio su disco in esaurimento
Le build di Xcode generano quantità significative di dati. Configura una pulizia automatica sul tuo runner:
# Check available disk space
df -h /
# Clean old DerivedData
rm -rf ~/Library/Developer/Xcode/DerivedData/*
# Remove old simulator runtimes
xcrun simctl runtime delete all
# Clean Homebrew cache
brew cleanup --prune=7
# Remove old CircleCI working directories
find /opt/circleci/workdir -maxdepth 1 -mtime +3 -exec rm -rf {} +
# Set up a weekly cron job for automatic cleanup
(crontab -l 2>/dev/null; echo "0 4 * * 0 rm -rf ~/Library/Developer/Xcode/DerivedData/* && brew cleanup --prune=7") | crontab -
11. Domande frequenti
Quanto costa un runner self-hosted CircleCI su Mac Mini M4?
Un Mac Mini M4 dedicato di MyRemoteMac parte da $85/mese con minuti di build illimitati. È notevolmente più economico dei runner macOS cloud di CircleCI, che costano circa $0,06-$0,12 al minuto (all'incirca $300-500/mese per team attivi). I runner self-hosted non hanno costi al minuto, quindi i tuoi costi sono prevedibili indipendentemente dal volume di build.
Posso usare un runner self-hosted CircleCI per build iOS e macOS?
Sì. Un runner self-hosted su un Mac Mini M4 può eseguire qualsiasi carico di lavoro macOS, incluse build iOS, build di app macOS, test di pacchetti Swift, test UI Xcode e automazione Fastlane. Poiché gira nativamente su Apple Silicon, le build sono più veloci rispetto ai runner cloud emulati o basati su Intel.
Qual è la differenza tra machine runner e container runner di CircleCI?
Il machine runner di CircleCI esegue i job direttamente sul sistema operativo della macchina host, cosa necessaria per le build macOS/iOS che richiedono Xcode, simulatori e framework Apple. Il container runner esegue i job all'interno di container Docker ed è disponibile solo su Linux. Per le build Mac devi usare il machine runner.
Come mantengo aggiornato il mio runner self-hosted CircleCI?
Il machine runner agent di CircleCI supporta gli aggiornamenti automatici per impostazione predefinita. Puoi anche aggiornare manualmente scaricando l'ultima release da CircleCI e sostituendo il binario. Si consiglia di verificare la presenza di aggiornamenti mensilmente e di mantenere aggiornati anche Xcode e macOS.
Un runner self-hosted è più veloce del macOS cloud di CircleCI?
Sì, tipicamente 2-3 volte più veloce per le clean build e fino a 9 volte più veloce per le build incrementali. I runner macOS cloud di CircleCI usano hardware Intel o M1 condiviso con ambienti effimeri, il che significa che ogni build parte con una cache fredda. Un Mac Mini M4 self-hosted offre prestazioni Apple Silicon dedicate, cache DerivedData e SPM persistenti e nessun tempo di attesa in coda.
Posso eseguire più job CircleCI contemporaneamente su un Mac Mini?
Sì. Il Mac Mini M4 ha una CPU a 10 core e 16 GB o più di RAM, che possono gestire comodamente 2-3 job di build simultanei. Per carichi di lavoro più pesanti, il Mac Mini M4 Pro con 14 core e 24 GB di RAM può gestire 4-6 job simultanei. Puoi configurare il numero massimo di task simultanei del runner nel file di configurazione del runner.