Your repo holds both an iOS app and its backend service: the backend uses docker-compose to spin up a database, a message queue, and a handful of microservices, and integration tests need to actually connect to those containers to run. For the iOS side you rented a cloud Mac mini from HireVPS to do Xcode builds, and everything worked fine — until you tried to make CI run a backend integration pass on the same box, and discovered there's no native Linux kernel on Apple Silicon. docker run just errors out saying it can't find the daemon. That's not a config mistake, it's an architectural fact: Docker on macOS has always run inside a "borrowed" environment.
Why you'd even want Linux containers on a cloud Mac
Monorepos are increasingly common, and a single PR might touch both the iOS client and the backend API at once — testing only the iOS side simply won't catch a protocol mismatch. The ideal pipeline looks like this: on the same runner, build and unit-test with Xcode first, then bring up the backend dependencies defined in docker-compose, run a round of end-to-end integration tests, and report everything together. The upside is obvious — no need to maintain two separate CI environments, and no need to punch holes in network policy for cross-machine communication. The one requirement is that this cloud Mac has to be able to run Linux containers.
There's no native Linux kernel on Apple Silicon, so any "run Docker" setup is really just booting a hidden Linux VM under the hood first — and performance comes down almost entirely to how much CPU and memory that VM gets.
Setup: picking a lightweight virtualization approach
There are two main paths to running containers on macOS: Docker Desktop, and Colima paired with the native docker CLI. Both boot a stripped-down Linux VM on top of Apple's Virtualization.framework under the hood — they differ in form factor and the use cases they suit.
Docker Desktop vs. Colima
| Aspect | Docker Desktop | Colima |
|---|---|---|
| Interface | GUI + background daemon | CLI only |
| Startup | Manual, or auto-launch at login | One command in a script |
| Resource footprint | Heavier, several persistent processes | Lightweight, starts/stops on demand |
| Best fit | Day-to-day local debugging | Unattended CI runners |
| Licensing | Paid license required at enterprise scale | Open source, free |
For CI running on an unattended runner, Colima is clearly the better fit: it doesn't depend on a graphical session, can be brought up with a single command in a shell script, and shuts down cleanly afterward — no orphaned processes left hogging memory.
Installation and resource tuning
On the cloud Mac mini, start by installing the toolchain with Homebrew:
brew install colima docker docker-compose docker-buildx
colima start \
--cpu 4 \
--memory 12 \
--disk 60 \
--vm-type=vz \
--mount-type=virtiofs
docker context use colima
docker compose -f docker-compose.ci.yml up -d --wait
--vm-type=vz selects Apple's native virtualization backend (noticeably faster than the older QEMU mode), and --mount-type=virtiofs gets the mounted project directory close to native disk I/O speed inside the container. Skip either flag and both build speed and file I/O take a visible hit.
There's no universal formula for resource allocation, but a reasonable starting point: give the Colima VM 50%–70% of the host's memory, and leave roughly half the CPU cores free for Xcode builds. Mapped against instance memory, a rough starting table looks like this (always confirm the current available specs in the console):
| Instance memory | Suggested Colima memory | Suggested Colima CPU |
|---|---|---|
| 16GB | 6GB | 2 cores |
| 32GB | 12GB | 4 cores |
| 48GB | 20GB | 6 cores |
| 64GB | 28GB | 8 cores |
If Xcode builds and Colima run at the same time, over-allocating memory to either side causes contention and swapping, which paradoxically makes builds slower. It's worth running the full pipeline a few times before wiring it into CI, just to dial in that balance.
Wiring it into CI: making the self-hosted runner Linux-container-aware
If the runner is a GitHub Actions self-hosted runner, just add a step that starts Colima, runs the tests, and tears everything down afterward — no extra service-container declarations needed:
jobs:
hybrid-ci:
runs-on: [self-hosted, macos, cloud-mac]
steps:
- uses: actions/checkout@v4
- name: Xcode build & unit test
run: |
xcodebuild -scheme App -destination "platform=iOS Simulator,name=iPhone 15" test
- name: Bring up backend containers
run: |
colima start --cpu 4 --memory 12 --vm-type=vz --mount-type=virtiofs
docker compose -f docker-compose.ci.yml up -d --wait
- name: Integration tests
run: ./scripts/run-integration-tests.sh
- name: Teardown
if: always()
run: |
docker compose -f docker-compose.ci.yml down -v
colima stop
That if: always() step matters: containers and the VM need to be torn down even when tests fail, otherwise a long-rented cloud Mac accumulates orphaned VMs over time, eating memory and slowing down the next build.
Caching strategy: reusing image layers and dependencies
If the Colima VM re-pulls images and reinstalls dependencies from scratch every time it restarts, CI runtime balloons. Two simple, effective habits fix that:
- Persist image layers to disk: don't run
colima deletebetween runs — stick tocolima stop/colima start. The VM's disk (by default under~/.colima) keeps already-pulled image layers, so a restart doesn't mean re-downloading everything. - Mount build-cache volumes: declare named volumes for dependency directories like
node_modules,vendor, or.cargoin your backend Dockerfiles. Combined withdocker compose's--wait, the first build is a bit slower, but subsequent incremental builds save the bulk of that time.
Combined with the virtiofs mount mentioned earlier, project-directory I/O generally stops being a bottleneck — the thing actually worth watching is the network layer. If integration tests hit external APIs, make sure the test environment points to a mock or sandbox endpoint, not silently against production.
Pitfalls and a checklist
Common issues people hit when wiring this up, roughly in priority order:
- Forgetting to switch the docker context: if Docker Desktop was used before installing Colima, the
dockercommand may still point at the old context — don't skipdocker context use colima. - Wrong VM type: older versions of Colima may default to
qemu; on Apple Silicon always explicitly pass--vm-type=vz, since the performance gap is significant. - Unbounded disk growth: uncleaned image layers keep eating into the space set by
--disk; it's worth periodically runningdocker system prune -af --volumesas part of the CI flow. - Resource contention from concurrent jobs: if other Xcode build jobs run in parallel on the same machine, scale down Colima's memory allocation accordingly to avoid OOM.
- Architecture-mismatched images: if the backend references base images that only support x86_64, they'll fall back to QEMU emulation on Apple Silicon and slow down dramatically — try to confirm images ship a native
arm64variant.
Once this pipeline is smoothed out, the same cloud Mac mini can double as both the iOS build machine and the backend integration test environment, with no need to juggle cross-machine networking or credentials. Submit a PR, and one pipeline gives you a complete pass/fail signal.
Frequently asked questions
Can Apple Silicon cloud Macs run Docker natively?
No. Docker Desktop and Colima both spin up a hidden Linux virtual machine via Virtualization.framework, and containers actually run inside that VM, so performance depends entirely on the CPU and RAM you allocate to it.
Colima or Docker Desktop for CI?
Pick Colima for CI: it's a CLI tool with a small footprint and fast startup, ideal for scripted boot inside an unattended runner. Docker Desktop suits local GUI debugging but isn't recommended on headless runners.
How should I size Colima's VM across different RAM tiers?
As a rule of thumb, give Colima's VM 50%–70% of host RAM — e.g. a 32GB host can allocate 12GB and 4 cores to Colima. Confirm the exact configuration currently available in the control panel, then tune it under load.
HireVPS
Try a dedicated cloud Mac mini today
Rent by the day, get SSH/VNC credentials in 2 minutes, and upgrade your configuration anytime.