New Mac mini M6 is now available 12-core CPU, US$280/month Learn more

macOS CI/CD · Self-hosted runner

A dedicated macOS build machine for the CI you already use

Turn a dedicated Mac mini into a self-hosted build node for GitHub Actions, GitLab or Jenkins. Flat monthly pricing instead of per-minute billing, no queueing, and build caches that stay on the machine so every run gets faster.

.github/workflows/ios.yml Runs on your Lumio Mac
name: iOS Build
on: [push, pull_request]
jobs:
  build:
    # jobs are dispatched to your own Mac mini
    runs-on: [self-hosted, macOS, ARM64]
    steps:
      - uses: actions/checkout@v4
      - run: xcodebuild -scheme App test \
          -destination 'platform=iOS Simulator,name=iPhone 16'

Connect GitHub Actions in three steps

Using GitHub Actions as an example, your Mac can be running builds within minutes of delivery. Other CI platforms follow a similar flow.

  1. 1

    Sign in to your Mac

    It is provisioned automatically after payment and is usually ready within 15–30 minutes. Get the IP and account from the client area and sign in over SSH.

    ssh macuser@<your-mac-ip>
  2. 2

    Register the runner

    Create a macOS runner under Settings → Actions → Runners in your repository, then download and register it with the commands shown.

    ./config.sh --url https://github.com/<org>/<repo> \
      --token <TOKEN>
  3. 3

    Run it as a service

    Install the runner as a service so it comes back online after a reboot, then use runs-on: self-hosted in your workflows.

    ./svc.sh install
    ./svc.sh start

Works with the major CI platforms

With full root access you can install any build agent that runs on macOS. These are the most common.

GitHub Actions

Self-hosted runner

The official runner supports macOS on Apple silicon and registers with the self-hosted, macOS and ARM64 labels by default.

./config.sh && ./svc.sh install

GitLab CI

GitLab Runner

Install GitLab Runner with Homebrew and register it to your project or group with the shell executor, so iOS jobs call Xcode directly.

brew install gitlab-runner

Jenkins

SSH agent

Install Java, add the Mac as an SSH agent node in Jenkins and give it a macos label for iOS jobs.

brew install openjdk

Buildkite

Buildkite Agent

Install the Buildkite Agent with Homebrew, add your agent token, and it starts picking up pipeline jobs.

brew install buildkite/buildkite/buildkite-agent

Self-hosted Mac or shared cloud runners?

Both have strengths. The more often you build and the larger the project, the more a self-hosted Mac pays off.

Lumio self-hosted Mac

  • BillingFlat monthly price, however many builds you run
  • QueueingThe machine is yours alone, so jobs start right away
  • CachingDependencies, DerivedData and simulators stay on disk for the next build
  • EnvironmentYou choose the Xcode version, toolchain and certificates
  • ScalingAdd another Mac when you need more concurrency

Shared cloud macOS runners

  • BillingBilled per build minute, and macOS minutes usually cost much more than Linux
  • QueueingJobs may wait for a free machine at peak times
  • CachingA fresh environment every run, so caches must be uploaded and restored
  • EnvironmentPre-built images, with Xcode versions updated on the platform's schedule
  • ScalingConcurrency scales elastically with no machines to maintain

Keep your Mac build machine reliable

A few practical tips that save a lot of trouble.

  • Pin the Xcode version

    Manage several Xcode versions with xcode-select or xcodes and set one explicitly in the pipeline, so a system update never breaks builds unexpectedly.

  • Handle the signing keychain

    Keep CI certificates in a dedicated keychain and unlock it with the security command before building, or manage certificates with fastlane match.

  • Clean the disk regularly

    DerivedData, old simulators and build artifacts pile up. A scheduled cleanup job keeps a full disk from failing your builds.

  • Use a separate runner user

    Run the build agent under its own system user, separate from your everyday login, for clearer permissions and better security.

macOS CI/CD runner FAQ

Common questions before connecting a Mac to your CI.

How many builds can one Mac run at once?

A runner handles one job at a time. You can register several runners on the same Mac for concurrency, but Xcode builds are CPU and memory hungry, so on 16GB we usually suggest one or two iOS builds at a time.

Should I use a self-hosted runner with a public repository?

It is not recommended. GitHub warns that pull requests to public repositories can run arbitrary code on self-hosted runners. Use self-hosted runners with private repositories, or require approval before workflows run.

Does the runner come back after a reboot?

Yes. Install the runner as a service the official way (svc.sh for GitHub, brew services for GitLab) and it starts and reconnects automatically on boot.

Can it sign iOS apps and upload to TestFlight?

Yes. Put your own certificates and provisioning profiles in the build machine's keychain, then use fastlane or xcodebuild to sign, archive and upload to App Store Connect and TestFlight automatically.

Which plan is best for CI?

Small teams can start with M4 Essential. Choose M4 Core (512GB) for heavy caches or several Xcode versions, and M6 for large projects where compile time is the bottleneck.

Can I add machines when I need more capacity?

Yes. Plans are billed monthly. Order another Mac when you need more concurrency; it is ready in 15–30 minutes after payment and can be registered as a new runner right away.

Give your pipeline a Mac of its own

A dedicated Mac mini from US$160/month, ready in 15–30 minutes after payment and running CI jobs shortly after.

View Mac plans