Offre

Runner auto-hébergé Mac mini GitHub Actions : guide production (launchd + isolation CI | 2026)

CI Mac mini · Runner auto-hébergé
2026-06-06 ~15 min

Page hub du runner auto-hébergé Mac mini GitHub Actions : architecture, installation, sécurité, acceptation iOS / Flutter. Louer un Mac pour valider puis passer au mensuel.

Qu'est-ce qu'un runner auto-hébergé GitHub Actions sur Mac mini ?

Un runner auto-hébergé Mac mini GitHub Actions est un environnement CI/CD géré par vous sur Apple Silicon. Il remplace les runners macOS GitHub avec caches persistants, builds iOS plus rapides et contrôle total de Xcode—idéal pour louer un Mac ou un Mac mini cloud dédié.

Comment installer un runner GitHub Actions sur Mac mini ?

  1. Créer un utilisateur ci dédié sur macOS
  2. Installer le paquet GitHub Actions runner
  3. Configurer avec un jeton d'enregistrement
  4. Service launchd pour démarrage au boot
  5. Labels pour le routage des workflows
  6. Valider avec un job vide

Intentions de recherche (5 types)

  1. Quoi — définition du runner auto-hébergé Mac mini
  2. Pourquoi — pourquoi l'iOS CI exige Mac mini (vs GitHub hébergé)
  3. Comment — installation production (4 étapes + launchd)
  4. Sécurité — isolation ci + protection fork PR
  5. Performance — optimisation cache 30 %–60 %
Mac mini GitHub Actions runner auto-hébergé : launchd et isolation utilisateur CI
Article hub du cluster Mac mini GitHub Actions Runner, lié à l'architecture Flutter iOS CI trois plans.

Runner auto-hébergé GitHub Actions (édition Mac mini)

Un runner auto-hébergé Mac mini GitHub Actions exécute les jobs workflow sur une instance Mac mini locale ou Mac cloud au lieu des runners macOS GitHub.

Cinq avantages clés sur Mac mini :

  • ✔ Caches de build durables (DerivedData / CocoaPods / SPM)
  • ✔ Version Xcode maîtrisée (Golden Image)
  • ✔ Coût CI fixe (pas de facturation à la minute)
  • ✔ Builds iOS nettement plus rapides (chaud 5–6 min)
  • ✔ Isolation entreprise (utilisateur ci + Keychain séparé)

Pourquoi l'iOS CI doit utiliser un runner auto-hébergé Mac mini

Trois goulots des runners GitHub hébergés

Problème macOS GitHub hébergé Mac mini auto-hébergé
Cache buildReset à chaque jobPersistant (Pods / DerivedData SSD)
Version XcodeSuit les mises à jour GitHubFigée (Golden Image)
Coût CIÀ la minuteFixe (louer un Mac / achat)
Vitesse buildFroid 8–12 minChaud 5–6 min

Conclusion

Runner GitHub hébergé = machine sans état
Runner Mac mini = CI avec mémoire

Cause racine des écarts iOS CI. Suite : Optimisation Flutter iOS CI : de 28 à 9 minutes.

Architecture production trois couches Mac mini CI

Modèle global

┌──────────────────────────────┐
│ Layer 1: launchd daemon      │  ← reliability (auto-restart / crash recovery)
├──────────────────────────────┤
│ Layer 2: ci user isolation   │  ← security (Keychain / permission boundary)
├──────────────────────────────┤
│ Layer 3: label routing       │  ← maintainability (workflow → Runner)
└──────────────────────────────┘

Couche 1 — démon launchd (stabilité)

launchd = systemd macOS. Redémarrage auto, reprise après reboot, relance après crash, niveau démon.

Trois clés plist obligatoires :

  • RunAtLoad = true — démarrage après login
  • KeepAlive = true — relance après crash
  • WorkingDirectoryobligatoire (cause n°1 offline)

Utiliser LaunchAgents (pas LaunchDaemons)—l'iOS CI a besoin du Keychain utilisateur pour la signature. Auto-login macOS pour la session ci.

Méthode Reprise reboot Reprise crash Fiabilité prod
nohup / screenInadapté
launchdProduction

Couche 2 — isolation utilisateur CI

Pourquoi pas un compte admin ?

  • sudo → surface d'attaque illimitée
  • Keychain lisible → fuite certificats
  • fork PR malveillant → compromission totale

Recommandé : utilisateur ci dédié

  • ❌ pas sudo, hors groupe admin
  • ✅ Keychain séparé (/Users/ci/Library/Keychains/)
  • ✅ groupe _developer (xcodebuild / simctl)
sudo dscl . -create /Users/ci UserShell /bin/zsh
sudo dscl . -create /Users/ci RealName "CI Runner"
sudo dscl . -create /Users/ci UniqueID 505
sudo dscl . -create /Users/ci PrimaryGroupID 20
sudo dscl . -create /Users/ci NFSHomeDirectory /Users/ci
sudo createhomedir -c -u ci
sudo passwd ci
sudo dscl . -append /Groups/_developer GroupMembership ci

Couche 3 — routage par labels

Taxonomie de labels = planificateur CI. Structure à trois niveaux :

runs-on: [self-hosted, macOS, ARM64, flutter-ios, xcode-16, m4]
           ┌──────────────┐  ┌───────────────────┐  ┌──────────────┐
           │ Platform     │  │ Workload          │  │ Hardware     │
           │ self-hosted  │  │ flutter-ios       │  │ m4, 16gb     │
           │ macOS, ARM64 │  │ xcode-16          │  │ region:tokyo │
           └──────────────┘  └───────────────────┘  └──────────────┘

Labels en ET (AND) ; workflow doit correspondre exactement ; plusieurs machines même label = équilibrage auto.

Installation complète runner Mac mini (production)

Étape 1 — Installer le runner

# Run as ci user
mkdir -p ~/actions-runner && cd ~/actions-runner
curl -fsSL -O https://github.com/actions/runner/releases/download/v2.316.1/actions-runner-osx-arm64-2.316.1.tar.gz
tar xzf actions-runner-osx-arm64-2.316.1.tar.gz

Étape 2 — Enregistrer

./config.sh \
  --url https://github.com/your-org/your-repo \
  --token YOUR_REGISTRATION_TOKEN \
  --name "$(hostname -s)" \
  --labels "self-hosted,macOS,ARM64,flutter-ios,xcode-16,m4,16gb" \
  --work _work \
  --replace \
  --unattended

Étape 3 — Config launchd (critique)

Enregistrer dans ~/Library/LaunchAgents/com.kvmboot.github-runner.plist :

<?xml version="1.0" encoding="UTF-8"?>
<plist version="1.0"><dict>
  <key>Label</key><string>com.kvmboot.github-runner</string>
  <key>ProgramArguments</key>
  <array><string>/Users/ci/actions-runner/run.sh</string></array>
  <key>WorkingDirectory</key><string>/Users/ci/actions-runner</string>
  <key>RunAtLoad</key><true/>
  <key>KeepAlive</key><true/>
  <key>EnvironmentVariables</key>
  <dict>
    <key>PATH</key>
    <string>/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin</string>
  </dict>
  <key>StandardOutPath</key><string>/Users/ci/Library/Logs/github-runner.log</string>
  <key>StandardErrorPath</key><string>/Users/ci/Library/Logs/github-runner.err</string>
</dict></plist>
WorkingDirectory indispensable
launchd utilise / par défaut. Sans WorkingDirectory, pas de .credentials → sortie silencieuse—GitHub offline, launchctl list loaded.

Étape 4 — Démarrer

launchctl load ~/Library/LaunchAgents/com.kvmboot.github-runner.plist
launchctl list | grep github-runner
tail -f ~/Library/Logs/github-runner.log   # expect: Listening for Jobs

Réseau et proxy (liste blanche sortante)

Le runner doit joindre *.github.com, api.github.com, *.actions.githubusercontent.com, objects.githubusercontent.com. Proxy dans plist EnvironmentVariables. Plages IP : api.github.com/meta.

Durcissement sécurité production

Risque majeur : fork PR sur dépôts publics. Trois lignes de défense :

1. Runner au niveau dépôt (pas organisation)

Enregistrer au niveau dépôt pour éviter la propagation latérale—un repo compromis expose tous les Keychains / Secrets.

2. Protection fork PR

GitHub → Settings → Actions → General, activer :

Exiger l'approbation pour les workflows fork des collaborateurs externes

Les fork PR ne doivent pas s'exécuter auto sur runners auto-hébergés. Voir isolation sécurité CI Mac cloud (surface fork PR).

3. Isolation des secrets

  • ❌ pas de .p12 / .env dans le home ci
  • ❌ pas de clés API en dur dans les workflows
  • ✅ GitHub Secrets + injection runtime ; certificats via Fastlane match + Keychain
concurrency:
  group: flutter-ios-${{ github.ref }}
  cancel-in-progress: true

Optimisation performance CI (iOS / Flutter)

Le runner auto-hébergé Mac mini amplifie l'optimisation iOS CI via caches locaux persistants :

Trois couches de cache

  • Cache CocoaPods (~/.cocoapods + ios/Pods)
  • DerivedData (chemin -derivedDataPath fixe)
  • Cache SPM / Flutter pub
Optimisation Gain typique Notes
Cache Pods~40 % tempsfroid 28 min → ~19 min
DerivedData~30 % tempschaud 12 min → ~6 min
Xcode figéstabilitésupprime changements cassants

Stratégie complète : Design cache iOS CI (DerivedData / CocoaPods / SPM).

Reconstruction runner en un clic (DR)

Après upgrade macOS majeur, dérive Golden Image ou incident sécurité, rebuild_runner.sh en ~5 minutes :

#!/usr/bin/env zsh
set -euo pipefail
CI_USER="ci"
PLIST_DEST="/Users/$CI_USER/Library/LaunchAgents/com.kvmboot.github-runner.plist"

sudo -u "$CI_USER" launchctl unload "$PLIST_DEST" 2>/dev/null || true
sudo -u "$CI_USER" bash -c "cd /Users/$CI_USER/actions-runner && ./config.sh remove --token \$(gh api -X POST /repos/your-org/your-repo/actions/runners/remove-token --jq '.token') 2>/dev/null || true"
sudo -u "$CI_USER" zsh /Users/$CI_USER/scripts/setup_runner.sh
sudo -u "$CI_USER" launchctl load "$PLIST_DEST"
echo "[OK] Runner rebuilt."

Vérifier que le runner est production-ready

Avant acceptation, confirmer l'environnement de base (checklist onboarding Mac cloud).

Niveau 1 — Runner en ligne

  • ✅ UI GitHub Idle
  • launchctl list | grep github-runner PID sain
  • ✅ log contient Listening for Jobs

Niveau 2 — Job vide

runs-on: [self-hosted, macOS, flutter-ios]
  • ✅ job assigné sous 30 s
  • ✅ nom runner et version OS affichés

Niveau 3 — Toolchain

xcodebuild -version    # matches Golden Image
flutter --version
pod --version
Symptôme Cause Action
Runner offlineWorkingDirectory absentlog .err, ajouter champ plist
Job en filelabels non concordantscomparer runs-on et labels
Boucle crashPATH manquantajouter EnvironmentVariables au plist

Positionnement production (E-E-A-T)

Conçu pour la CI production : toolchains déterministes (Golden Image), isolation fork PR, fiabilité après reboot et crash.

Modèle trois couches : macOS (launchd), isolation (sandbox ci), routage (labels GitHub Actions).

Implémentation Mac mini CI validée sur Mac cloud kvmboot—nœuds runner mensuels et machines sprint journalières quand vous louez un Mac.

FAQ (mots-clés longue traîne)

Un Mac mini peut-il exécuter un runner GitHub Actions ?

Oui—configuration production courante pour l'iOS CI. Avec launchd, environnement runner auto-hébergé GitHub Actions (macOS) stable long terme.

Combien plus rapide qu'un runner GitHub hébergé ?

Typiquement 30 %–60 % sur iOS CI grâce à la persistance CocoaPods / DerivedData—les runners hébergés repartent à zéro chaque job.

Différence launchd vs brew services ?

launchd est le framework démon système macOS (équivalent systemd) ; brew services est un wrapper inadapté aux runners non-Homebrew. Production = plist manuel.

Runner offline : comment diagnostiquer ?

Par priorité :

  1. launchctl list | grep github-runner
  2. WorkingDirectory dans le plist
  3. labels runs-on identiques à l'enregistrement

Combien de runners sur un Mac mini ?

16 Go → 1 recommandé ; 24 Go → 1–2 (léger). xcodebuild sature la RAM—multi-instances avec concurrency.

Déployer ce runner sur un Mac mini cloud

Meilleur hôte pour un runner auto-hébergé Mac mini GitHub Actions : Apple Silicon M4, Xcode ARM64 natif, mémoire unifiée, ~4 W idle. SIP, Gatekeeper et Keychains séparés renforcent l'isolation sécurité runner—rayon d'explosion fork PR limité au home ci.

Migration Flutter iOS CI ? kvmboot Mac mini cloud M4 : location journalière → nœud runner mensuel—voir les offres.

Offre limitée Voir les plans