Инструмент управления контейнерами, совместимый с Docker, построенный на фреймворке Apple Containerization
Mocker — это CLI-инструмент с поддержкой Docker Compose, работающий нативно на macOS с помощью фреймворка Containerization от Apple (требуется macOS 26+). Он «говорит» на том же языке, что и Docker: те же команды, те же флаги, тот же формат вывода — поэтому все существующие скрипты и привычки работают без изменений.
Просто замените docker на mocker
# Было
docker compose up -d
docker ps
docker logs my-app
docker exec -it my-app sh
# Стало — те же команды, нативная среда выполнения Apple, без Docker Desktop
mocker compose up -d
mocker ps
mocker logs my-app
mocker exec -it my-app sh
Существующий docker-compose.yml работает без каких-либо изменений.
Что нового
Полная актуальная история релизов доступна в файле CHANGELOG — он перегенерируется автоматически при каждом выпуске.
Возможности
-
Совместимость с Docker CLI —
run,ps,stop,rm,exec,logs,build,pull,push,images,tag,rmi,inspect,stats -
Управление сетями —
network create/ls/rm/inspect/connect/disconnect -
Управление томами —
volume create/ls/rm/inspect -
Docker Compose v2 —
compose up/down/ps/logs/restartс учётом порядка зависимостей -
GUI в строке меню — нативное приложение на SwiftUI (скоро)
-
Хранение состояния в JSON — все метаданные сохраняются в
~/.mocker/ -
Конкурентность Swift 6 — полная потокобезопасность на основе акторов (actors)
|
Примечание
|
Замечание о совместимости: Mocker разбирает все флаги Docker CLI для полной взаимозаменяемости, однако часть флагов не поддерживается средой выполнения Containerization от Apple и вызовет предупреждение или ошибку. Подробнее о том, какие команды полностью функциональны, а какие не поддерживаются, см. в COMMANDS.md. |
Требования
| Компонент | Версия |
|---|---|
macOS |
26.0+ (Sequoia) |
Swift |
6.0+ |
Xcode |
16.0+ |
|
Примечание
|
Фреймворк Apple Containerization требует macOS 26 на Apple Silicon. Компьютеры Mac на Intel не поддерживаются. |
Установка
Homebrew (рекомендуется)
brew tap us/tap
brew install mocker
Сборка из исходного кода
git clone https://github.com/us/mocker.git
cd mocker
swift build -c release
cp .build/release/mocker /usr/local/bin/mocker
Быстрый старт
# Загрузить образ
mocker pull nginx:1.25
# Запустить контейнер
mocker run -d --name webserver -p 8080:80 nginx:1.25
# Список запущенных контейнеров
mocker ps
# Просмотр логов
mocker logs webserver
# Остановить и удалить
mocker stop webserver
mocker rm webserver
Использование
Жизненный цикл контейнера
# Запуск с переменными окружения и томами
mocker run -d \
--name myapp \
-p 8080:80 \
-e APP_ENV=production \
--env-file .env \
-v /host/data:/app/data \
myimage:latest
# Интерактивный запуск (на переднем плане)
mocker run --name temp alpine:latest
# Принудительное удаление работающего контейнера
mocker rm -f myapp
# Выполнить команду внутри работающего контейнера
mocker exec myapp env
# Следить за логами
mocker logs -f myapp
Образы
# Загрузить конкретный тег
mocker pull postgres:15
# Список образов
mocker images
# Список только идентификаторов образов
mocker images -q
# Поставить тег на образ
mocker tag alpine:latest my-registry.io/alpine:v1
# Удалить образ
mocker rmi my-registry.io/alpine:v1
# Собрать из Dockerfile
mocker build -t myapp:latest .
# Мультиплатформенная сборка (флаг --platform повторяется для каждой архитектуры)
mocker build --platform linux/amd64 --platform linux/arm64 -t myapp:latest .
# Отправить в реестр
mocker push my-registry.io/myapp:latest
Манифест-листы (мультиархитектурные образы)
# Просмотр OCI image index
mocker manifest inspect myrepo/multi:latest
# Создать манифест-лист из существующих образов под конкретные архитектуры
mocker manifest create myrepo/multi:latest myrepo/app:amd64 myrepo/app:arm64
# Добавить дочерний образ в существующий список (заменяет запись той же платформы)
mocker manifest add myrepo/multi:latest myrepo/app:arm64
# Удалить запись по спецификации платформы или дайджесту
mocker manifest rm myrepo/multi:latest linux/amd64
mocker manifest rm myrepo/multi:latest sha256:cb96058800ca…
# Переопределить метаданные платформы для записи
mocker manifest annotate myrepo/multi:latest myrepo/app:arm64 --variant v8
# Отправить собранный список в реестр
mocker manifest push myrepo/multi:latest
Сборка под экзотические архитектуры
mocker build --platform linux/ppc64le|s390x|riscv64 работает для Dockerfile, состоящих только из слоёв (FROM / COPY / CMD), но завершается ошибкой Exec format error при наличии любой инструкции RUN. BuildKit-VM в Apple container build — это arm64 Linux VM без обработчиков QEMU binfmt_misc для архитектур, отличных от arm64/amd64. linux/amd64 работает только потому, что Apple Silicon поставляется с аппаратной трансляцией Rosetta 2. Отслеживание в апстриме: apple/container#1496.
До тех пор, пока Apple не добавит поддержку QEMU, существуют три обходных пути:
| Путь | Компромисс |
|---|---|
Удалённый сборщик. Направьте mocker на Linux-хост с уже зарегистрированным QEMU |
Требуется доступный удалённый Linux-хост (нативный ppc64le или x86/arm с |
Запустить машину Podman параллельно с mocker. Её VM на Fedora CoreOS имеет зарегистрированный |
Требуется постоянно работающая QEMU VM — дополнительный расход памяти и усложнение инфраструктуры. |
|
Ручная настройка; разовое действие для каждой нужной архитектуры. |
Для arm64 и amd64 (Rosetta 2) нативный путь быстрее и официально поддерживается — эмуляция экзотических архитектур остаётся обходным решением до появления соответствующей поддержки в апстриме.
Просмотр и статистика
# Просмотр контейнера (вывод JSON)
mocker inspect myapp
# Просмотр нескольких объектов или с ограничением по типу
mocker inspect container1 container2 alpine:latest
mocker inspect --type image alpine:latest
# JSON-массив в формате Docker ImageInspect; при необходимости выбор платформы
mocker image inspect --platform linux/amd64 alpine:latest
# Статистика использования ресурсов
mocker stats --no-stream
Сети
# Создать сеть
mocker network create mynet
# Список сетей
mocker network ls
# Подключить контейнер
mocker network connect mynet myapp
# Отключить
mocker network disconnect mynet myapp
# Просмотреть
mocker network inspect mynet
# Удалить
mocker network rm mynet
Тома
# Создать именованный том
mocker volume create pgdata
# Список томов
mocker volume ls
# Просмотр (показывает точку монтирования)
mocker volume inspect pgdata
# Удалить
mocker volume rm pgdata
Docker Compose
# Запустить все сервисы (в фоне)
mocker compose -f docker-compose.yml up -d
# Список контейнеров Compose
mocker compose -f docker-compose.yml ps
# Просмотр логов сервиса
mocker compose -f docker-compose.yml logs web
# Перезапустить сервис
mocker compose -f docker-compose.yml restart api
# Остановить и удалить
mocker compose -f docker-compose.yml down
Пример docker-compose.yml:
version: "3.8"
services:
web:
image: nginx:1.25
ports:
- "8080:80"
depends_on:
- api
api:
image: myapp:latest
environment:
- DB_HOST=db
- DB_PORT=5432
depends_on:
- db
db:
image: postgres:15
environment:
POSTGRES_PASSWORD: secret
POSTGRES_DB: myapp
volumes:
- pgdata:/var/lib/postgresql/data
volumes:
pgdata:
Система
# Информация о системе
mocker system info
# Удалить остановленные контейнеры и неиспользуемые ресурсы
mocker system prune -f
Архитектура
mocker/
├── Sources/
│ ├── MockerKit/ # Общая основная библиотека
│ │ ├── Models/ # Типы данных (ContainerInfo, ImageInfo, ...)
│ │ ├── Config/ # MockerConfig (пути ~/.mocker/)
│ │ ├── Container/ # ContainerEngine + ContainerStore (actor)
│ │ ├── Image/ # ImageManager + ImageStore (actor)
│ │ ├── Network/ # NetworkManager (actor)
│ │ ├── Volume/ # VolumeManager (actor)
│ │ └── Compose/ # Парсер ComposeFile + ComposeOrchestrator
│ ├── Mocker/ # Исполняемый файл CLI
│ │ ├── Commands/ # По одному файлу на группу команд
│ │ └── Formatters/ # TableFormatter, JSON-вывод
│ └── MockerApp/ # Приложение SwiftUI в строке меню (macOS 26+)
│ ├── MenuBar/
│ ├── ViewModels/
│ └── Views/
└── Tests/
├── MockerKitTests/ # Юнит-тесты основной библиотеки
└── MockerTests/ # Интеграционные тесты CLI
Ключевые архитектурные решения
| Аспект | Подход |
|---|---|
Потокобезопасность |
Все движки и менеджеры являются типами |
Хранение состояния |
JSON-файлы в |
Разбор CLI |
|
Разбор YAML |
Библиотека |
Именование в Compose |
Конвенция Docker v2: |
JSON-вывод |
Всегда обёрнут в массив |
Каталог данных
Mocker хранит всё состояние в ~/.mocker/:
~/.mocker/
├── containers/ # Метаданные контейнеров (один JSON-файл на контейнер)
├── images/ # Метаданные образов
├── networks/ # Метаданные сетей
└── volumes/ # Метаданные томов + каталоги с данными
└── pgdata/
└── _data/
Совместимость с Docker
Mocker нацелен на полную совместимость CLI с Docker. Ключевые совпадающие модели поведения:
-
Сообщения об ошибках:
Error response from daemon: … -
inspectвсегда возвращает JSON-массив, даже для одного объекта -
Идемпотентность
pull: повторная загрузка существующего образа выводит «Image is up to date» -
Именование контейнеров Compose:
project-service-1(дефис, не подчёркивание) -
stopиrmвозвращают в ответ идентификатор, переданный пользователем -
Короткие ID состоят из 12 символов (первые 12 символов полного 64-символьного шестнадцатеричного ID)
Сборка и тестирование
# Собрать все цели
swift build
# Запустить все тесты
swift test
# Запустить конкретный набор тестов
swift test --filter MockerKitTests
# Запустить CLI напрямую
swift run mocker --help
Производительность
Бенчмарки выполнены на Apple M-серии, macOS 26 (hyperfine --warmup 5 --runs 15):
| Инструмент | Запуск контейнера | По сравнению с Docker |
|---|---|---|
Docker Desktop |
320 мс |
baseline |
Apple |
1 030 мс |
в 3,2× медленнее |
Mocker |
1 153 мс |
в 3,6× медленнее |
Модель Apple «одна VM на контейнер» обменивает скорость запуска на более строгую изоляцию — каждый контейнер получает собственную лёгкую Linux VM. Mocker добавляет лишь ~120 мс накладных расходов на управление поверх среды выполнения Apple.
Пропускная способность CPU и памяти (sysbench внутри контейнера, 30 с):
| Метрика | Docker | Apple Container |
|---|---|---|
CPU events/s |
7 958 |
7 894 |
Пропускная способность памяти |
13 340 MiB/s |
13 119 MiB/s |
Производительность вычислений идентична — граница VM практически не создаёт накладных расходов для нагрузок на CPU и память.
Как это работает
Mocker делегирует Apple CLI container операции жизненного цикла контейнеров (run, stop, exec, logs, build). Операции с образами (pull, list, tag, rmi) используют Containerization.ImageStore напрямую. Такой гибридный подход уже сегодня даёт полноценный инструмент, совместимый с Docker, на macOS 26:
| Операция | Бэкенд |
|---|---|
|
Подпроцесс |
|
|
|
|
|
Хранилище образов Apple CLI (показывает все загруженные и собранные образы) |
|
RSS/CPU процесса VM через |
Проброс портов |
Постоянный подпроцесс |
Дорожная карта
-
✓ Полная совместимость флагов Docker CLI (111 команд)
-
✓ Поддержка Docker Compose v2
-
✓ Управление сетями и томами
-
❏ GUI в строке меню
-
✓ Реальное выполнение контейнеров на macOS 26 (через Apple
containerCLI) -
✓
mocker build— делегирует вcontainer buildс потоковым выводом -
✓
mocker stats— реальные CPU% и память из процесса VM -
✓ Проброс портов (
-p) — пользовательский TCP-прокси в виде подпроцесса -
❏ Аутентификация в реестре (
mocker login) -
❏
mocker compose --scale -
❏ Живые метрики контейнеров в строке меню (CPU, память, логи)
-
❏ Отображение размера слоёв образа
-
❏ Прямая интеграция с фреймворком Containerization (ожидается совместимость с vminit)
Участие в разработке
Вклад в проект приветствуется! Пожалуйста, ознакомьтесь с docs/contributing.md для получения инструкций.
# Сделать форк и клонировать
git clone https://github.com/yourname/mocker.git
# Создать ветку для функциональности
git checkout -b feat/my-feature
# Внести изменения и запустить тесты
swift test
# Зафиксировать по конвенции Conventional Commits
git commit -m "feat: add my feature"
Лицензия
AGPL-3.0 — подробности в файле LICENSE.