Ваш репозиторий одновременно содержит iOS-приложение и его backend-сервисы: backend поднимается через docker-compose — база данных, очередь сообщений и несколько микросервисов, — а интеграционные тесты по-настоящему подключаются к этим контейнерам, чтобы вообще запуститься. Для iOS-части вы арендовали облачный Mac mini у HireVPS для сборки в Xcode, и всё шло гладко — до тех пор, пока не захотелось на той же машине прогонять и backend-интеграционные тесты. Тут выясняется, что на Apple Silicon нет нативного Linux-ядра, и docker run сразу падает с ошибкой «не найден демон». Это не проблема конфигурации — это архитектурное ограничение: Docker на macOS всегда работал «через посредника».
Сценарий: зачем на облачном Mac запускать Linux-контейнеры
Monorepo встречаются всё чаще: один PR может одновременно менять iOS-клиент и backend API, и если тестировать только iOS-сторону, несоответствие протокола просто не будет обнаружено. Идеальный пайплайн выглядит так: на одном и том же раннере сначала Xcode собирает приложение и прогоняет unit-тесты, затем поднимаются backend-зависимости из docker-compose, выполняется раунд end-to-end интеграционных тестов, и в конце результаты сводятся в единый отчёт. Плюс очевиден — не нужно поддерживать две отдельные CI-среды, а также не приходится открывать сетевые правила для межмашинного взаимодействия. Единственное условие — этот облачный Mac должен уметь запускать Linux-контейнеры.
На Apple Silicon нет нативного Linux-ядра, поэтому любое решение для «запуска Docker» по сути сначала стартует скрытую Linux-виртуальную машину — и производительность почти целиком зависит от того, сколько CPU и памяти этой VM выделено.
Подготовка: выбираем лёгкое решение для виртуализации
На macOS для запуска контейнеров есть в основном два пути: Docker Desktop и Colima (в паре с нативным docker CLI). Оба варианта под капотом используют Virtualization.framework от Apple для старта компактной Linux-VM, различия — в форм-факторе и сценариях применения.
Docker Desktop против Colima
| Критерий | Docker Desktop | Colima |
|---|---|---|
| Форма взаимодействия | GUI + фоновый демон | Только командная строка |
| Способ запуска | Вручную или автостарт при логине | Одна команда в скрипте |
| Потребление ресурсов | Выше, держит несколько процессов | Легковесное, запускается по потребности |
| Подходящий сценарий | Локальная повседневная отладка | Безнадзорный CI-раннер |
| Ограничения лицензии | На корпоративном масштабе требуется платная лицензия | Открытый исходный код, бесплатно |
Для CI, работающего на безнадзорном раннере, Colima явно подходит лучше: он не зависит от графической сессии, поднимается одной командой в shell-скрипте и глушится сразу после завершения работы — без осиротевших процессов, съедающих память.
Установка и настройка ресурсов
На облачном Mac mini сначала устанавливаем инструментарий через 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 использует нативный backend виртуализации от Apple (заметно быстрее старого режима на QEMU), а --mount-type=virtiofs приближает производительность чтения/записи смонтированной директории проекта к скорости локального диска. Без этих двух параметров и скорость сборки, и файловый I/O заметно проседают.
Универсальной формулы для распределения ресурсов нет, но есть рабочая отправная точка: под VM Colima отводить 50–70% памяти хоста, а под CPU — примерно половину ядер, оставляя вторую половину для сборок Xcode. По объёму памяти машины можно ориентировочно стартовать так (точную доступную конфигурацию уточняйте в консоли):
| Память машины | Рекомендуемая память для Colima | Рекомендуемое число CPU для Colima |
|---|---|---|
| 16GB | 6GB | 2 ядра |
| 32GB | 12GB | 4 ядра |
| 48GB | 20GB | 6 ядер |
| 64GB | 28GB | 8 ядер |
Если Xcode-сборка и Colima работают одновременно, слишком высокое выделение памяти заставит их конкурировать друг с другом и уходить в swap, из-за чего сборка, наоборот, замедлится. Эту точку баланса стоит откалибровать, прогнав несколько раз весь пайплайн целиком ещё до вывода в продуктивный CI.
Интеграция с CI: чтобы self-hosted раннер понимал Linux-контейнеры
Если раннер — self-hosted типа GitHub Actions, достаточно добавить в job шаг запуска Colima, прогона тестов и последующей очистки — без дополнительного объявления service-контейнеров:
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
Шаг if: always() критически важен: даже если тесты провалились, контейнеры и виртуальную машину нужно погасить — иначе на долгосрочно арендованном облачном Mac будут накапливаться осиротевшие VM, съедающие память и замедляющие следующую сборку.
Стратегия кэширования: слои образов и переиспользование зависимостей
Если после каждого перезапуска VM Colima заново тянуть образы и переустанавливать зависимости, время CI сильно растянется. Два простых и эффективных приёма:
- Сохранять слои образов на диске: не вызывать
colima deleteкаждый раз, использовать толькоcolima stop/colima start— диск виртуальной машины (по умолчанию в~/.colima) сохранит уже скачанные слои образов, и после перезапуска повторная загрузка не потребуется. - Монтировать тома для build-кэша: в backend-Dockerfile объявить именованные volume для директорий зависимостей вроде
node_modules,vendor,.cargo; в паре с флагом--waitуdocker composeпервая сборка будет чуть медленнее, но последующие инкрементальные сборки экономят большую часть времени.
В связке с упомянутым выше монтированием virtiofs чтение/запись директории проекта практически не становится узким местом — реальное внимание стоит уделить сетевому уровню: если интеграционные тесты обращаются к внешним API, обязательно настройте для тестовой среды отдельные mock-адреса или sandbox-эндпоинты, чтобы CI незаметно не стучался в продакшен.
Чек-лист граблей и проверок
Реальные проблемы, с которыми чаще всего сталкиваются при интеграции, по приоритету:
- Забыли переключить docker context: если до Colima использовался Docker Desktop, команда
dockerможет по-прежнему указывать на старый context — шагdocker context use colimaпропускать нельзя. - Неверно выбран тип VM: старые версии Colima по умолчанию могли использовать
qemu— на Apple Silicon обязательно явно указывайте--vm-type=vz, разница в производительности заметна невооружённым глазом. - Бесконтрольный рост диска: неочищенные слои образов будут постоянно занимать место, заданное параметром
--disk; рекомендуется периодически запускать в CI-процессеdocker system prune -af --volumes. - Конкуренция за ресурсы при параллельных задачах: если на той же машине параллельно выполняются другие Xcode-сборки, память, выделенную Colima, нужно соответственно уменьшать, чтобы избежать OOM.
- Образы под несовпадающую архитектуру: если backend ссылается на базовые образы, поддерживающие только x86_64, на Apple Silicon они пойдут через слой эмуляции QEMU и скорость резко упадёт — старайтесь убедиться, что у образа есть нативный вариант для
arm64.
Отладив этот процесс, один и тот же облачный Mac mini сможет одновременно выступать и машиной для iOS-сборок, и средой для backend-интеграционных тестов — без необходимости координировать сеть и учётные данные между разными машинами. После пуша PR один пайплайн выдаёт полный сигнал pass/fail.
Часто задаваемые вопросы
Может ли облачный Mac на Apple Silicon запускать Docker нативно?
Нет. И Docker Desktop, и Colima поднимают скрытую Linux-виртуалку через Virtualization.framework, а контейнеры работают внутри неё — производительность целиком зависит от выделенных CPU и памяти.
Что выбрать для CI: Colima или Docker Desktop?
Для CI лучше Colima: это CLI-инструмент с малым потреблением ресурсов и быстрым запуском, удобный для скриптового старта на раннере без присмотра. Docker Desktop больше подходит для локальной отладки с GUI.
Как подбирать ресурсы Colima под разный объём памяти тарифа?
Как ориентир — отдавайте VM Colima 50–70% памяти хоста, например для хоста на 32GB это около 12GB и 4 ядра. Точную доступную конфигурацию проверяйте в панели управления и подстраивайте под нагрузочным тестом.
HireVPS Cloud Mac
Попробуйте выделенный облачный Mac mini уже сегодня
Аренда от одного дня, доступ по SSH/VNC за 2 минуты, конфигурацию можно повысить в любой момент.