1. ¿Por qué usar un Self-Hosted CircleCI Runner en Mac?
CircleCI ofrece entornos de ejecución macOS en la nube, pero conllevan costes y limitaciones significativos. Los recursos macOS en CircleCI utilizan un sistema basado en créditos donde cada minuto en un ejecutor macOS consume de 50 a 100 créditos según la resource class. Para equipos que ejecutan compilaciones iOS frecuentes, esto puede sumar rápidamente $300-$500 por mes o más.
Un self-hosted runner en un Mac Mini M4 dedicado de MyRemoteMac elimina por completo la facturación por minuto. Obtiene una máquina Apple Silicon dedicada con almacenamiento persistente, cachés precargadas y acceso root completo por una tarifa mensual fija desde $75/mes. Aquí tiene una comparación detallada:
| Característica | CircleCI Cloud macOS | MyRemoteMac Self-Hosted |
|---|---|---|
| Modelo de costes | 50-100 créditos/min (~$0.06-$0.12/min) | $75/mes tarifa fija (minutos ilimitados) |
| Arquitectura | Intel x86 o M1 (compartido) | Apple M4 (dedicado, último modelo) |
| Velocidad de compilación | ~14 min (proyecto iOS mediano) | ~5 min (mismo proyecto) |
| Persistencia de caché | Efímero (debe restaurar en cada job) | Persistente en disco (instantáneo) |
| Tiempo de espera en cola | 30s - 5min (varía según el plan) | 0s (hardware dedicado) |
| Privacidad / Control de datos | Infraestructura compartida | Máquina dedicada, control total |
| Software personalizado | Solo imagen preinstalada | Acceso root completo, cualquier software |
Beneficio clave: Con un self-hosted runner persistente, DerivedData, las cachés de Swift Package Manager y CocoaPods se preservan entre compilaciones. Esto por sí solo puede reducir los tiempos de compilación en un 50-70% comparado con los entornos macOS efímeros en la nube de CircleCI que comienzan desde cero cada vez. Combinado con el rendimiento superior de single-thread del chip M4, sus compilaciones iOS serán drásticamente más rápidas.
2. Requisitos previos
Antes de comenzar, asegúrese de tener lo siguiente:
- Un servidor Mac Mini M4 de MyRemoteMac (desde $75/mes)
- Una cuenta de CircleCI con un plan Performance, Scale o Server (los self-hosted runners requieren un plan de pago)
- Acceso SSH a su Mac Mini (incluido con su suscripción de MyRemoteMac)
- Una cuenta de Apple Developer (para la firma de código y perfiles de aprovisionamiento)
- Familiaridad básica con YAML, configuración de CircleCI y comandos de terminal
3. Paso 1: Conectarse por SSH al Mac Mini e instalar dependencias
Primero, conéctese a su Mac Mini M4 por SSH. Habrá recibido sus credenciales al configurar su servidor MyRemoteMac. Necesitamos instalar Xcode y las herramientas necesarias para compilaciones iOS antes de configurar el runner de CircleCI.
Conectarse por 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
Instalar Homebrew y 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
Instalar Xcode (versión completa)
Para compilaciones iOS, necesita la aplicación Xcode completa. La forma más rápida de instalarla en un servidor headless es usando 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
Instalar simuladores iOS y herramientas de compilación
# 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. Paso 2: Instalar el agente CircleCI Runner
CircleCI usa un agente machine runner para conectar su Mac Mini a la plataforma CircleCI. El machine runner recibe jobs de CircleCI y los ejecuta directamente en su host macOS. Esto es diferente del container runner (que solo funciona en Linux).
Crear un usuario dedicado para el Runner
Se recomienda crear un usuario dedicado para ejecutar el agente de CircleCI por aislamiento de seguridad:
# 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)
Descargar e instalar el agente Runner
# 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
Configurar el agente Runner
Cree el archivo de configuración del runner. Necesitará su token de autenticación del runner del panel de CircleCI (cubierto en el Paso 3). Por ahora, cree la estructura del archivo de configuración:
# 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
Crear un Launch Agent de macOS para persistencia
Para asegurar que el runner se inicie automáticamente al arrancar y se reinicie si falla, cree un LaunchDaemon de 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: El agente runner no se conectará hasta que agregue un token de autenticación válido. Complete el Paso 3 primero para generar el token, luego actualice el archivo runner-agent-config.yaml con el token real y reinicie el servicio.
5. Paso 3: Configurar el Runner en el panel de CircleCI
Ahora necesita registrar su runner en la interfaz web de CircleCI y generar un token de autenticación. Esto conecta su Mac Mini a su organización de CircleCI.
Crear una Resource Class
En CircleCI, los self-hosted runners se organizan por resource classes. Una resource class es una etiqueta que mapea su .circleci/config.yml a un conjunto específico de runners.
- Vaya a Panel de CircleCI → Organization Settings → Self-Hosted Runners
- Haga clic en "Create Resource Class"
- Establezca el Namespace con el nombre de su organización (p. ej.,
your-org) - Establezca el nombre de la Resource Class con algo descriptivo (p. ej.,
mac-runner) - Esto crea un identificador de resource class:
your-org/mac-runner
Generar un token de autenticación del Runner
- Después de crear la resource class, haga clic en "Create New Token"
- Dé al token un nombre descriptivo (p. ej.,
mac-mini-m4-token) - Copie el token generado inmediatamente — solo se mostrará una vez
Actualizar la configuración del Runner con su 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 vez conectado, el runner debería aparecer como "Online" en el panel de CircleCI bajo Self-Hosted Runners. Si no aparece en 60 segundos, verifique el archivo de log en busca de mensajes de error.
Usar el CLI de CircleCI (Alternativa)
También puede gestionar runners mediante el CLI de 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. Paso 4: Crear su .circleci/config.yml para compilaciones iOS
Cree un archivo .circleci/config.yml en la raíz de su repositorio. La diferencia clave con una configuración estándar de CircleCI es usar machine: true con su resource_class personalizado para apuntar a su self-hosted runner.
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: El valor resource_class: your-org/mac-runner debe coincidir exactamente con la resource class que creó en el panel de CircleCI. Si no coincide, los jobs permanecerán en cola indefinidamente.
7. Paso 5: Optimizar con caché y paralelismo
Una de las mayores ventajas de un self-hosted runner es la caché persistente. Debido a que el sistema de archivos del runner es persistente, no necesita cargar y descargar cachés como lo hace con los recursos en la nube de CircleCI. Sin embargo, hay optimizaciones adicionales para maximizar la velocidad de compilación.
Aprovechar DerivedData persistente
Como el disco del runner persiste entre compilaciones, DerivedData ya está cacheado automáticamente. Use una ruta consistente:
# 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 {} +
Persistencia de Workspace entre jobs
Use los workspaces de CircleCI para pasar artefactos entre jobs en el mismo 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
Ejecución paralela de pruebas
- 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
División de pruebas de CircleCI
Para suites de pruebas grandes, use la división de pruebas integrada de CircleCI para distribuir pruebas entre runners paralelos:
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. Ejemplos de Workflows
Aquí tiene ejemplos de workflows completos y listos para producción para escenarios comunes de CI/CD de iOS.
Pipeline completo de compilación, pruebas y despliegue 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
Ejemplo de integración con Fastlane
Si usa Fastlane para la automatización de compilaciones, aquí le mostramos cómo integrarlo con su CircleCI self-hosted runner:
# 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. Comparación de rendimiento
Aquí tiene una comparación detallada de rendimiento y costes entre los recursos macOS en la nube de CircleCI y un Mac Mini M4 self-hosted de MyRemoteMac:
Benchmarks de tiempo de compilación
| Escenario | CircleCI Cloud macOS | Self-Hosted Mac Mini M4 | Mejora |
|---|---|---|---|
| Compilación limpia (app mediana) | 14 min | 5 min | 2.8x más rápido |
| Compilación incremental | 14 min (sin caché) | 1.5 min | 9.3x más rápido |
| Resolución de dependencias SPM | 3-5 min (descarga cada vez) | 5 seg (cacheado en disco) | ~60x más rápido |
| Suite de pruebas unitarias (500 pruebas) | 8 min | 2.5 min | 3.2x más rápido |
| Tiempo de espera en cola | 30s - 5 min | 0 seg | Instantáneo |
Análisis de costes mensuales
| Tamaño del equipo | Compilaciones/Mes | Coste CircleCI Cloud | Coste MyRemoteMac | Ahorro mensual |
|---|---|---|---|---|
| Desarrollador individual | 100 compilaciones (10 min promedio) | $100/mes | $75/mes | $25/mes |
| Equipo pequeño (5) | 500 compilaciones (10 min promedio) | $500/mes | $75/mes | $425/mes |
| Equipo mediano (15) | 1500 compilaciones (10 min promedio) | $1,500/mes | $179/mes (M4 Pro) | $1,321/mes |
| Empresa (50+) | 5000+ compilaciones | $5,000+/mes | $358/mes (2x M4 Pro) | $4,642+/mes |
Conclusión: Para cualquier equipo que ejecute más de ~75 compilaciones por mes, un Mac Mini M4 self-hosted se amortiza de inmediato. El ahorro se multiplica además porque las compilaciones son más rápidas en hardware dedicado con cachés precargadas, lo que significa que cada compilación consume menos minutos en primer lugar.
10. Solución de problemas comunes
El Runner se desconecta o aparece como "Offline"
El agente runner puede perder la conexión por problemas de red o un proceso caído. El LaunchDaemon debería reiniciarse automáticamente, pero si no lo hace:
# 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 no encontrada o jobs atascados en cola
Si los jobs se quedan en cola con "No matching runner found", la resource class en su configuración no coincide con el panel:
# 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'
Errores de firma de código en Xcode
La firma de código en una máquina CI requiere una gestión cuidadosa del keychain. El proceso del runner puede no tener acceso al keychain de inicio de sesión:
# 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
El simulador no arranca o se agota el tiempo de espera
Los simuladores pueden quedar en mal estado en máquinas CI de larga ejecución. Reinícielos entre compilaciones:
# 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
Espacio en disco insuficiente
Las compilaciones de Xcode generan cantidades significativas de datos. Configure una limpieza automática en su 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. Preguntas frecuentes
¿Cuánto cuesta un CircleCI self-hosted runner en Mac Mini M4?
Un Mac Mini M4 dedicado de MyRemoteMac comienza en $75/mes con minutos de compilación ilimitados. Esto es significativamente más económico que los runners macOS en la nube de CircleCI que cuestan aproximadamente $0.06-$0.12 por minuto (aproximadamente $300-500/mes para equipos activos). Los self-hosted runners no tienen cargos por minuto, por lo que sus costes son predecibles independientemente del volumen de compilaciones.
¿Puedo usar un CircleCI self-hosted runner para compilaciones iOS y macOS?
Sí. Un self-hosted runner en un Mac Mini M4 puede ejecutar cualquier carga de trabajo macOS, incluyendo compilaciones iOS, compilaciones de apps macOS, pruebas de paquetes Swift, pruebas de interfaz XCUITest y automatización con Fastlane. Como se ejecuta de forma nativa en Apple Silicon, las compilaciones son más rápidas que en runners en la nube emulados o basados en Intel.
¿Cuál es la diferencia entre CircleCI machine runner y container runner?
CircleCI machine runner ejecuta los jobs directamente en el sistema operativo de la máquina host, lo cual es necesario para compilaciones macOS/iOS que requieren Xcode, simuladores y frameworks de Apple. Container runner ejecuta jobs dentro de contenedores Docker y solo está disponible en Linux. Para compilaciones Mac, debe usar el machine runner.
¿Cómo mantengo actualizado mi CircleCI self-hosted runner?
El agente CircleCI machine runner admite actualizaciones automáticas de forma predeterminada. También puede actualizar manualmente descargando la última versión de CircleCI y reemplazando el binario. Se recomienda verificar las actualizaciones mensualmente y mantener Xcode y macOS actualizados también.
¿Es un self-hosted runner más rápido que CircleCI cloud macOS?
Sí, típicamente 2-3x más rápido para compilaciones limpias y hasta 9x más rápido para compilaciones incrementales. Los runners macOS en la nube de CircleCI usan hardware Intel o M1 compartido con entornos efímeros, lo que significa que cada compilación comienza con una caché vacía. Un Mac Mini M4 self-hosted tiene rendimiento dedicado de Apple Silicon, cachés persistentes de DerivedData y SPM, y sin tiempos de espera en cola.
¿Puedo ejecutar múltiples jobs de CircleCI simultáneamente en un Mac Mini?
Sí. El Mac Mini M4 tiene un CPU de 10 núcleos y 16GB o más de RAM, lo que puede manejar cómodamente 2-3 jobs de compilación concurrentes. Para cargas de trabajo más pesadas, el Mac Mini M4 Pro con 14 núcleos y 24GB de RAM puede manejar 4-6 jobs concurrentes. Puede configurar las tareas concurrentes máximas del runner en el archivo de configuración del runner.