# How to choose and set up a macOS server for iOS CI/CD

> What an iOS build server needs: Apple silicon, the right macOS and Xcode, enough CPU, memory and disk, a runner in a desktop session and working signing.

Difficulty: Advanced\
Tested on: macOS Sequoia 15, macOS Tahoe 26

Continuous integration for iOS and macOS apps needs a real Mac: Xcode runs only on macOS, and macOS runs only on Apple hardware. A remote Mac in a data center also brings a stable connection, a fixed IP address for webhooks and allow lists, and no office computer that someone switches off at night. This guide covers versions, sizing, the runner and code signing.

## The short answer

For App Store builds, choose an Apple silicon Mac with a macOS version that runs the Xcode Apple currently requires. Give it enough memory and disk for two Xcode versions and their simulators, keep a logged-in session for UI tests, and store signing secrets outside your repository.

## Step 1: Match macOS and Xcode to Apple's requirements

1. **Check today's upload rule.** Since 28 April 2026, App Store uploads must be built with Xcode 26 or later.
2. **Plan for the next deadline.** Apple has announced that the 27 SDKs will be required from April 2027. Note the Xcode you will need then.
3. **Find the macOS that Xcode needs** on Apple's Xcode system requirements page. Xcode 27, for example, needs macOS Tahoe 26.6 or later and a Mac with Apple silicon.
4. **Pick a plan that offers it.** Our order form lists the macOS versions for each macOS plan; Apple Silicon macOS VPS plans are prepared on request.

### Apple silicon or Intel?

macOS Tahoe 26 is the last macOS release for Intel-based Macs; macOS 27 and current Xcode releases need Apple silicon. Intel Macs remain useful for testing older macOS versions or x86_64 builds, but a new App Store build server should be Apple silicon. On Apple silicon, builds run natively and Xcode downloads arm64 simulator runtimes, which saves disk space. Because Apple's Virtualization framework does not offer nested virtualization for macOS guests, you cannot run further virtual machines inside an Apple Silicon macOS VPS; choose a macOS VDS for that.

## Step 2: Size the server

| Resource | Starting point | Why |
|---|---|---|
| CPU | 8 or more cores | Shorter clean builds and parallel test runs |
| Memory | 16 GB, or 32 GB for parallel simulators | Xcode, the compiler and each simulator need their share |
| Disk | 100 GB or more free | Two Xcode versions, runtimes, DerivedData, archives |
| macOS | A version the required Xcode supports | Apple's Xcode system requirements |
| Access | SSH plus a graphical session | Screen Sharing for setup, UI tests and keychain prompts |
| Network | Stable connection and a fixed IP address | Webhooks, allow lists, dependency downloads |

These are rules of thumb: large projects and parallel jobs need more. Measure your own builds.

## Step 3: Prepare the Mac

Connect as described in [first steps on a macOS server](/guides/macos-server-first-steps), then:

```bash
sudo xcode-select -s /Applications/Xcode-26.app
xcodebuild -version
sudo xcodebuild -runFirstLaunch
sudo pmset -a sleep 0
```

**Verify:** `xcodebuild -version` prints the expected release and `pmset -g` shows `sleep 0`.

For UI tests, the runner needs a logged-in desktop session: enable **Automatically log in as** in **System Settings › Users & Groups** (it is not available while FileVault is on), so the session returns after a restart.

## Step 4: Install the CI runner

- **Xcode Cloud** is Apple's hosted CI and needs no server.
- **GitHub Actions**, **GitLab Runner** and **Jenkins** all support self-hosted macOS agents; follow their official installation guides and register the runner for your repository or group.
- **fastlane** automates build, test, signing and upload steps on any of them.

Run the runner as a user agent in the logged-in session rather than only as a background daemon, so UI tests and keychain access work.

> **Warning**
>
> A self-hosted runner executes whatever code a pipeline gives it. Use it only with private repositories you trust, keep macOS and Xcode updated and limit who can change the pipeline configuration.

## Step 5: Code signing on a remote Mac

1. **Use an App Store Connect API key.** Create a team key in App Store Connect and store it in your CI secrets. Apple lets you download the private key only once.
2. **Keep certificates out of the repository.** Store certificates and profiles encrypted, for example with fastlane match, or import them from CI secrets.
3. **Use a temporary keychain per job**, created at the start and deleted at the end:

```bash
security create-keychain -p "$KEYCHAIN_PASSWORD" build.keychain
security set-keychain-settings -lut 21600 build.keychain
security unlock-keychain -p "$KEYCHAIN_PASSWORD" build.keychain
security import signing.p12 -k build.keychain -P "$P12_PASSWORD" -T /usr/bin/codesign
security list-keychains -d user -s build.keychain login.keychain
security set-key-partition-list -S apple-tool:,apple: -s -k "$KEYCHAIN_PASSWORD" build.keychain
```

At the end of the job:

```bash
security delete-keychain build.keychain
```

4. **Let Xcode sign automatically.** `xcodebuild` can use the API key on a machine without a signed-in Apple Account:

```bash
xcodebuild -scheme MyApp -configuration Release -archivePath build/MyApp.xcarchive archive -allowProvisioningUpdates -authenticationKeyPath "$ASC_KEY_PATH" -authenticationKeyID "$ASC_KEY_ID" -authenticationKeyIssuerID "$ASC_ISSUER_ID"
```

5. **Rotate and revoke.** Revoke keys that may have leaked and review regularly who has access to signing.

## Keep the disk healthy

Remove Xcode versions you no longer need, delete unavailable simulators with `xcrun simctl delete unavailable` and clear old DerivedData on a schedule. Plan space for the next Xcode before Apple's next deadline.

## Troubleshooting

**`errSecInternalComponent` or signing prompts that hang.** The keychain is locked or the partition list is missing. Unlock it and run `set-key-partition-list` as above.

**UI tests fail only in CI.** The runner has no graphical session. Run it in the logged-in user session and keep automatic login on.

**"No space left on device".** Clean simulators, DerivedData and archives; see [macOS VPS and VDS](/guides/macos-vps).

## Next steps

- What each macOS line offers: [macOS VPS and VDS](/guides/macos-vps).
- Secure SSH access to the Mac: [SSH keys](/guides/ssh-keys).

## Frequently asked questions

### Can I build iOS apps on a Linux or Windows server?

No. Xcode and the iOS SDK run only on macOS, and macOS runs only on Apple hardware. Linux servers are still useful in the same pipeline for back-end services, Android builds and artifact storage.

### Which macOS version should my build server run?

A version supported by the Xcode you need, as listed on Apple's Xcode system requirements page. Keep the version the same on all build machines so that builds are reproducible.

### How much disk space does a build server need?

Plan for at least 100 GB of free space for one pipeline. Xcode, simulator runtimes, DerivedData and archives grow quickly, and around Apple's yearly deadlines you may need two Xcode versions side by side.

### Do I need a graphical session for CI?

For command-line builds, SSH is enough. UI tests, the Simulator and some keychain prompts need a logged-in graphical session, so set up automatic login and use Screen Sharing for setup.

### Should I use Xcode Cloud or my own remote Mac?

Xcode Cloud is Apple's hosted CI with a monthly allowance of compute hours in the Apple Developer Program. A self-hosted runner on your own Mac gives full control of the toolchain, persistent caches and no per-minute billing. Many teams combine both.

### Can several projects share one build server?

Yes, if the server has enough cores, memory and disk for the jobs that run at the same time. Limit parallel jobs, use a temporary keychain per job and keep each project's Xcode version installed side by side.

---

Source: <https://hyperdc.com/guides/products/macos-server-for-ios-ci>\
Updated: 2026-10-09
