iOS & macOS CI

Running Xcode CI on a dedicated M4 Mac mini.

Cloud CI bills Mac minutes at a premium, and shared runners queue at the worst possible time. A dedicated M4 Mac mini turns your iOS pipeline into a flat monthly cost with zero queue — this guide covers when that trade wins and how to set it up.

The economics: per-minute Mac CI vs a flat machine

Hosted CI providers price macOS runners at roughly 2–10× their Linux rate. A team shipping daily builds with a 15–25 minute pipeline typically burns hundreds of dollars a month in Mac minutes alone — before flaky-retry waste and queue time.

A dedicated M4 Mac mini flips that to a flat rate. The M4’s 10-core CPU builds most mid-size apps faster than the virtualized Intel or shared-silicon runners many CI clouds still serve, and the machine is warm: dependency caches, DerivedData, and simulator runtimes persist between builds instead of being rebuilt from a cold image every run.

Setting up the runner

Any self-hosted runner model works the same way: install the agent on the mini, point it at your repo, and tag your workflow to use it. GitHub Actions, GitLab Runner, Buildkite, and Xcode Cloud fallback flows all support this pattern.

  • Install Xcode + command-line tools once over Screen Sharing, sign in to your Apple Developer account, and accept licenses.
  • Install your CI agent (e.g. GitHub’s actions-runner) as a LaunchDaemon so it survives reboots.
  • Keep signing certificates in the login keychain and use your CI’s secret store for the unlock step.
  • Pin simulator runtimes you test against, and cache SPM/CocoaPods on disk — that’s the speed win shared runners can’t give you.

Why the network matters more than people think

CI is upload-heavy: archives, dSYMs, and TestFlight uploads move gigabytes outbound. Consumer-grade or shared hosting connections choke exactly there. A symmetric business-fiber line uploads a 500MB archive in seconds, so the "upload to App Store Connect" step stops being the long pole in your pipeline.

A fixed IP also means your runner’s identity is stable for IP-allowlisted registries, artifact stores, and internal APIs.

Dedicated rental vs buying a mini

Buying a mini makes sense if you have an office with reliable power, a static-IP business line, and someone to babysit reboots and macOS updates. Renting a racked one makes sense when you want the machine without the facilities problem: UPS-backed power, auto-restart, monitored uptime, and a real ISP-grade connection — for less than most teams spend on Mac CI minutes.

Common questions

Can I run multiple runners on one mini?

Yes — an M4 with 16GB comfortably runs 1–2 concurrent iOS build jobs. Beyond that, simulator boot storms start to contend; add a second machine instead.

Do I get full admin on the machine?

Yes. It’s a dedicated machine with your own login — install any toolchain, Xcode version, or agent you want. It’s not a shared VM.

How do reboots and macOS updates work?

The machine never sleeps and auto-restarts after power events. You control when macOS updates — no forced restarts mid-pipeline.

Skip the setup — rent the machine.

A dedicated M4 Mac mini on symmetric business fiber. Private VLAN, fixed IP, online 24/7. From $139/mo, billed 3 months at a time.

See pricing