1. Warum einen Self-Hosted CircleCI Runner auf dem Mac verwenden?
CircleCI bietet cloudbasierte macOS-Ausführungsumgebungen, doch diese sind mit erheblichen Kosten und Einschränkungen verbunden. macOS-Ressourcen bei CircleCI verwenden ein Credit-basiertes System, bei dem jede Minute auf einem macOS-Executor je nach Resource Class 50-100 Credits verbraucht. Für Teams mit häufigen iOS-Builds kann sich das schnell auf $300-$500 pro Monat oder mehr summieren.
Ein Self-Hosted Runner auf einem dedizierten Mac Mini M4 von MyRemoteMac eliminiert die Abrechnung pro Minute vollständig. Sie erhalten eine dedizierte Apple-Silicon-Maschine mit persistentem Speicher, warmen Caches und vollem Root-Zugriff für eine feste monatliche Gebühr ab $85/Monat. Hier ist ein detaillierter Vergleich:
| Merkmal | CircleCI Cloud macOS | MyRemoteMac Self-Hosted |
|---|---|---|
| Kostenmodell | 50-100 Credits/Min. (~$0,06-$0,12/Min.) | $85/Mon. pauschal (unbegrenzte Minuten) |
| Architektur | Intel x86 oder M1 (geteilt) | Apple M4 (dediziert, neueste) |
| Build-Geschwindigkeit | ~14 Min. (mittelgroßes iOS-Projekt) | ~5 Min. (dasselbe Projekt) |
| Cache-Persistenz | Ephemer (muss bei jedem Job wiederhergestellt werden) | Persistent auf der Festplatte (sofort) |
| Wartezeit in der Warteschlange | 30 Sek. - 5 Min. (je nach Plan) | 0 Sek. (dedizierte Hardware) |
| Datenschutz / Datenkontrolle | Geteilte Infrastruktur | Dedizierte Maschine, volle Kontrolle |
| Individuelle Software | Nur vorinstalliertes Image | Voller Root-Zugriff, beliebige Software |
Wichtigster Vorteil: Mit einem persistenten Self-Hosted Runner bleiben DerivedData, Swift-Package-Manager-Caches und CocoaPods zwischen den Builds erhalten. Allein das kann die Build-Zeiten im Vergleich zu den ephemeren Cloud-macOS-Umgebungen von CircleCI, die jedes Mal bei null beginnen, um 50-70 % verkürzen. In Kombination mit der überlegenen Single-Thread-Leistung des M4-Chips werden Ihre iOS-Builds dramatisch schneller.
2. Voraussetzungen
Bevor Sie beginnen, stellen Sie sicher, dass Sie über Folgendes verfügen:
- Einen Mac Mini M4 Server von MyRemoteMac (ab $85/Mon.)
- Ein CircleCI-Konto mit einem Performance-, Scale- oder Server-Plan (Self-Hosted Runner erfordern einen kostenpflichtigen Plan)
- SSH-Zugang zu Ihrem Mac Mini (im Lieferumfang Ihres MyRemoteMac-Abonnements enthalten)
- Einen Apple-Developer-Account (für Code-Signierung und Provisioning-Profile)
- Grundkenntnisse in YAML, CircleCI-Konfiguration und Terminal-Befehlen
3. Schritt 1: Per SSH auf Ihren Mac Mini zugreifen und Abhängigkeiten installieren
Verbinden Sie sich zunächst per SSH mit Ihrem Mac Mini M4. Ihre Anmeldedaten haben Sie beim Einrichten Ihres MyRemoteMac-Servers erhalten. Wir müssen Xcode und die für iOS-Builds erforderlichen Werkzeuge installieren, bevor wir den CircleCI Runner einrichten.
Per SSH verbinden
# 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
Homebrew und Xcode Command Line Tools installieren
# 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
Xcode (Vollversion) installieren
Für iOS-Builds benötigen Sie die vollständige Xcode-Anwendung. Der schnellste Weg, sie auf einem Server ohne Bildschirm zu installieren, ist die Verwendung von 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
iOS-Simulatoren und Build-Tools installieren
# 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. Schritt 2: Den CircleCI Runner Agent installieren
CircleCI verwendet einen Machine Runner Agent, um Ihren Mac Mini mit der CircleCI-Plattform zu verbinden. Der Machine Runner empfängt Jobs von CircleCI und führt sie direkt auf Ihrem macOS-Host aus. Das unterscheidet sich vom Container Runner (der nur unter Linux funktioniert).
Einen dedizierten Benutzer für den Runner erstellen
Es wird empfohlen, zur Sicherheitsisolation einen dedizierten Benutzer zum Ausführen des CircleCI Agents zu erstellen:
# 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)
Den Runner Agent herunterladen und installieren
# 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
Den Runner Agent konfigurieren
Erstellen Sie die Runner-Konfigurationsdatei. Sie benötigen Ihr Runner-Authentifizierungs-Token aus dem CircleCI-Dashboard (in Schritt 3 behandelt). Erstellen Sie zunächst die Struktur der Konfigurationsdatei:
# 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
Einen macOS Launch Agent für die Persistenz erstellen
Um sicherzustellen, dass der Runner beim Booten automatisch startet und nach einem Absturz neu startet, erstellen Sie einen macOS LaunchDaemon:
# 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
Wichtig: Der Runner Agent stellt keine Verbindung her, bis Sie ein gültiges Authentifizierungs-Token hinzufügen. Führen Sie zuerst Schritt 3 aus, um das Token zu generieren, aktualisieren Sie dann die Datei runner-agent-config.yaml mit dem echten Token und starten Sie den Dienst neu.
5. Schritt 3: Den Runner im CircleCI-Dashboard konfigurieren
Nun müssen Sie Ihren Runner in der CircleCI-Weboberfläche registrieren und ein Authentifizierungs-Token generieren. Dies verbindet Ihren Mac Mini mit Ihrer CircleCI-Organisation.
Eine Resource Class erstellen
In CircleCI werden Self-Hosted Runner nach Resource Classes organisiert. Eine Resource Class ist ein Label, das Ihre .circleci/config.yml einem bestimmten Satz von Runnern zuordnet.
- Gehen Sie zu CircleCI Dashboard → Organization Settings → Self-Hosted Runners
- Klicken Sie auf "Create Resource Class"
- Setzen Sie den Namespace auf Ihren Organisationsnamen (z. B.
your-org) - Setzen Sie den Namen der Resource Class auf etwas Aussagekräftiges (z. B.
mac-runner) - Dadurch wird ein Resource-Class-Bezeichner erstellt:
your-org/mac-runner
Ein Runner-Authentifizierungs-Token generieren
- Klicken Sie nach dem Erstellen der Resource Class auf "Create New Token"
- Geben Sie dem Token einen aussagekräftigen Namen (z. B.
mac-mini-m4-token) - Kopieren Sie das generierte Token sofort — es wird nur einmal angezeigt
Die Runner-Konfiguration mit Ihrem Token aktualisieren
# 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"
Nach der Verbindung sollte der Runner im CircleCI-Dashboard unter Self-Hosted Runners als "Online" erscheinen. Wenn er nicht innerhalb von 60 Sekunden erscheint, überprüfen Sie die Protokolldatei auf Fehlermeldungen.
Verwendung der CircleCI CLI (Alternative)
Sie können Runner auch über die CircleCI CLI verwalten:
# 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. Schritt 4: Ihre .circleci/config.yml für iOS-Builds erstellen
Erstellen Sie eine .circleci/config.yml-Datei im Stammverzeichnis Ihres Repositorys. Der wesentliche Unterschied zu einer Standard-CircleCI-Konfiguration ist die Verwendung von machine: true mit Ihrer benutzerdefinierten resource_class, um Ihren Self-Hosted Runner anzusprechen.
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
Hinweis: Der Wert resource_class: your-org/mac-runner muss exakt mit der Resource Class übereinstimmen, die Sie im CircleCI-Dashboard erstellt haben. Stimmt er nicht überein, bleiben Jobs unbegrenzt in der Warteschlange.
7. Schritt 5: Mit Caching und Parallelisierung optimieren
Einer der größten Vorteile eines Self-Hosted Runners ist das persistente Caching. Da das Dateisystem des Runners persistent ist, müssen Sie Caches nicht wie bei CircleCI-Cloud-Ressourcen hoch- und herunterladen. Es gibt jedoch zusätzliche Optimierungen, um Ihre Build-Geschwindigkeit zu maximieren.
Persistente DerivedData nutzen
Da die Runner-Festplatte zwischen den Builds persistent bleibt, sind DerivedData bereits automatisch zwischengespeichert. Verwenden Sie einen konsistenten Pfad:
# 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 {} +
Workspace-Persistenz zwischen Jobs
Verwenden Sie CircleCI-Workspaces, um Artefakte zwischen Jobs im selben Workflow weiterzugeben:
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
Parallele Testausführung
- 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
CircleCI Test-Splitting
Verwenden Sie für große Test-Suites das integrierte Test-Splitting von CircleCI, um Tests über parallele Runner zu verteilen:
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. Workflow-Beispiele
Hier sind vollständige, produktionsreife Workflow-Beispiele für gängige iOS-CI/CD-Szenarien.
Vollständige iOS-Build-, Test- und Deploy-Pipeline
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
Fastlane-Integrationsbeispiel
Wenn Sie Fastlane für Ihre Build-Automatisierung verwenden, erfahren Sie hier, wie Sie es in Ihren CircleCI Self-Hosted Runner integrieren:
# 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. Performance-Vergleich
Hier ist ein detaillierter Performance- und Kostenvergleich zwischen CircleCI-Cloud-macOS-Ressourcen und einem Self-Hosted Mac Mini M4 von MyRemoteMac:
Build-Zeit-Benchmarks
| Szenario | CircleCI Cloud macOS | Self-Hosted Mac Mini M4 | Verbesserung |
|---|---|---|---|
| Clean-Build (mittelgroße App) | 14 Min. | 5 Min. | 2,8x schneller |
| Inkrementeller Build | 14 Min. (kein Cache) | 1,5 Min. | 9,3x schneller |
| SPM-Abhängigkeitsauflösung | 3-5 Min. (jedes Mal Download) | 5 Sek. (auf der Festplatte zwischengespeichert) | ~60x schneller |
| Unit-Test-Suite (500 Tests) | 8 Min. | 2,5 Min. | 3,2x schneller |
| Wartezeit in der Warteschlange | 30 Sek. - 5 Min. | 0 Sek. | Sofort |
Monatliche Kostenanalyse
| Teamgröße | Builds/Monat | CircleCI-Cloud-Kosten | MyRemoteMac-Kosten | Monatliche Ersparnis |
|---|---|---|---|---|
| Einzelentwickler | 100 Builds (Ø 10 Min.) | $100/Mon. | $85/Mon. | $25/Mon. |
| Kleines Team (5) | 500 Builds (Ø 10 Min.) | $500/Mon. | $85/Mon. | $425/Mon. |
| Mittleres Team (15) | 1500 Builds (Ø 10 Min.) | $1.500/Mon. | $229/Mon. (M4 Pro) | $1.271/Mon. |
| Enterprise (50+) | 5000+ Builds | $5.000+/Mon. | $458/Mon. (2x M4 Pro) | $4.542+/Mon. |
Fazit: Für jedes Team, das mehr als ~75 Builds pro Monat durchführt, amortisiert sich ein Self-Hosted Mac Mini M4 sofort. Die Kostenersparnis verstärkt sich zusätzlich, weil Builds auf dedizierter Hardware mit warmen Caches schneller sind, was bedeutet, dass jeder Build von vornherein weniger Minuten verbraucht.
10. Häufige Probleme beheben
Runner trennt die Verbindung oder wird als "Offline" angezeigt
Der Runner Agent kann aufgrund von Netzwerkproblemen oder eines abgestürzten Prozesses die Verbindung verlieren. Der LaunchDaemon sollte automatisch neu starten, aber falls nicht:
# 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 nicht gefunden oder Jobs bleiben in der Warteschlange hängen
Wenn Jobs mit "No matching runner found" in der Warteschlange bleiben, stimmt die Resource Class in Ihrer Konfiguration nicht mit dem Dashboard überein:
# 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'
Xcode-Code-Signing-Fehler
Die Code-Signierung auf einer CI-Maschine erfordert eine sorgfältige Verwaltung des Schlüsselbunds. Der Runner-Prozess hat möglicherweise keinen Zugriff auf den Login-Schlüsselbund:
# 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
Simulator startet nicht oder es kommt zu einem Timeout
Simulatoren können auf langlaufenden CI-Maschinen in einen fehlerhaften Zustand geraten. Setzen Sie sie zwischen den Builds zurück:
# 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
Speicherplatz wird knapp
Xcode-Builds erzeugen erhebliche Datenmengen. Richten Sie eine automatische Bereinigung auf Ihrem Runner ein:
# 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. Häufig gestellte Fragen
Wie viel kostet ein CircleCI Self-Hosted Runner auf dem Mac Mini M4?
Ein dedizierter Mac Mini M4 von MyRemoteMac beginnt bei $85/Monat mit unbegrenzten Build-Minuten. Das ist deutlich günstiger als die Cloud-macOS-Runner von CircleCI, die etwa $0,06-$0,12 pro Minute kosten (grob $300-500/Monat für aktive Teams). Self-Hosted Runner haben keine Kosten pro Minute, sodass Ihre Kosten unabhängig vom Build-Volumen vorhersehbar sind.
Kann ich einen CircleCI Self-Hosted Runner für iOS- und macOS-Builds verwenden?
Ja. Ein Self-Hosted Runner auf einem Mac Mini M4 kann jeden macOS-Workload ausführen, einschließlich iOS-Builds, macOS-App-Builds, Swift-Paket-Tests, Xcode-UI-Tests und Fastlane-Automatisierung. Da er nativ auf Apple Silicon läuft, sind Builds schneller als auf emulierten oder Intel-basierten Cloud-Runnern.
Was ist der Unterschied zwischen CircleCI Machine Runner und Container Runner?
Der CircleCI Machine Runner führt Jobs direkt auf dem Betriebssystem des Host-Rechners aus, was für macOS/iOS-Builds erforderlich ist, die Xcode, Simulatoren und Apple-Frameworks benötigen. Der Container Runner führt Jobs in Docker-Containern aus und ist nur unter Linux verfügbar. Für Mac-Builds müssen Sie den Machine Runner verwenden.
Wie halte ich meinen CircleCI Self-Hosted Runner aktuell?
Der CircleCI Machine Runner Agent unterstützt standardmäßig automatische Updates. Sie können auch manuell aktualisieren, indem Sie die neueste Version von CircleCI herunterladen und die Binärdatei ersetzen. Es wird empfohlen, monatlich nach Updates zu suchen und Xcode und macOS ebenfalls aktuell zu halten.
Ist ein Self-Hosted Runner schneller als CircleCI-Cloud-macOS?
Ja, typischerweise 2-3x schneller bei Clean-Builds und bis zu 9x schneller bei inkrementellen Builds. CircleCI-Cloud-macOS-Runner verwenden geteilte Intel- oder M1-Hardware mit ephemeren Umgebungen, was bedeutet, dass jeder Build mit einem kalten Cache startet. Ein Self-Hosted Mac Mini M4 bietet dedizierte Apple-Silicon-Leistung, persistente DerivedData- und SPM-Caches und keine Wartezeiten in der Warteschlange.
Kann ich mehrere CircleCI-Jobs gleichzeitig auf einem Mac Mini ausführen?
Ja. Der Mac Mini M4 hat eine 10-Kern-CPU und 16 GB oder mehr RAM, was problemlos 2-3 gleichzeitige Build-Jobs bewältigen kann. Für anspruchsvollere Workloads kann der Mac Mini M4 Pro mit 14 Kernen und 24 GB RAM 4-6 gleichzeitige Jobs verarbeiten. Sie können die maximale Anzahl gleichzeitiger Tasks des Runners in der Runner-Konfigurationsdatei festlegen.