OpenClaw Docker на Mac-облаке в 2026: Exit 137/OOM, права томов uid 1000, DNS и кратчайший путь к openclaw doctor

У операторов, которые запускают OpenClaw в Docker на арендованных Mac в облаке, часто всплывают код выхода 137, Permission denied на смонтированном конфиге или ситуация, когда HTTPS на хосте проходит, а внутри контейнера — нет; дальше начинаются дни переустановки образов. В статье зафиксировано, кому она адресована (SRE и одиночные разработчики на съёмных Mac), что вы получите (упорядоченный чеклист и матрицу симптомов в духе официальной практики Compose 2026) и как устроена логика изложения: сначала память и cgroups, затем тома с uid 1000, потом DNS Docker, далее openclaw doctor, порт 18789 и момент, когда разумнее отказаться от контейнеров в пользу нативного macOS.

Схема шлюза OpenClaw в Docker на хосте Mac-облака

В этой статье

1. Триада готовности: процесс поднят, порт проброшен, том доступен на запись

Официальные сценарии Docker и Docker Compose оборачивают шлюз OpenClaw в контейнер. Хост Mac-облака по-прежнему владеет квотами RAM и CPU, делает bind-mount каталога ~/.openclaw (или пользовательского пути к конфигу) и публикует 18789 или другой сопоставленный порт для проверок с loopback или через SSH-туннели. В отличие от ноутбука на столе, облачные Mac обычно приходят с ограниченной памятью, часто без GUI-сессии и с образами, где процесс типично идёт не от root, а от пользователя node с uid/gid 1000. Пока эти факты не усвоены, любая правка конфига делается не на том уровне абстракции.

Определите готовность как три наблюдаемых факта, которые можно вставить в тикет: контейнер работает или healthy, в выводе docker compose ps видна ожидаемая привязка ports, а команды вроде openclaw status или ваш health probe проходят внутри контейнера без ошибок прав. Маршрутизация моделей, вебхуки Slack и Cron имеют смысл только после того, как триада зелёная. Типичные ошибки Compose: пути на хосте, которых нет (Docker создаёт каталоги от root), read-only там, где шлюзу нужна запись состояния, или переполнение небольшого корневого тома слоями образов и кэшем сборки — снаружи это похоже на «случайные» падения, пока df -h не покажет правду.

Зафиксируйте имя compose-проекта, имена сервисов, опубликованные порты и абсолютные пути на хосте для конфига и рабочей области. Одна строка в runbook экономит часы, когда вы сверяетесь с гайдами по апгрейду, вебхукам или тихому разбору Cron: у всех одна и та же топология, а не догадки, о какой машине речь.

2. Разбор болевых точек (нумерованный)

  1. Exit 137 и OOM: Docker отображает лимиты памяти Linux cgroups на рабочую нагрузку. Когда срабатывает OOM killer ядра, Docker часто показывает код выхода 137 (128 + SIGKILL 9). Скачивание и сборка образов едят RAM сильнее, чем устойчивый трафик шлюза; узел, который «часами нормальный», может умереть за минуты на docker compose build. Всегда отмечайте, 137 случился на этапе build или run — лечение разное.
  2. Владение томом и uid 1000: Если вы создали ~/.openclaw на хосте от root или под личным пользователем, процесс node в контейнере не сможет писать openclaw.json, логи или файлы workspace. Сбой может выглядеть как тихий цикл перезапусков без явного стека и часто ошибочно списывается на «плохие release notes».
  3. DNS Docker и корпоративный egress: Если curl https://api.anthropic.com на хосте успешен, а docker exec … curl — нет, почти всегда дело в неверных DNS в контейнере, переменных HTTP(S)_PROXY или в том, что доверенные сертификаты / прокси TLS-intercept не видны внутри. Менять API-ключи до починки сетевого пути — трата времени и квоты.
  4. Health-check и гонки зависимостей: Агрессивный depends_on без достаточного start_period заливает логи «connection refused», похожими на баги приложения. Сначала докажите, что шлюз слушает порт, прежде чем зависимые сервисы начнут его долбить.

Вместе эти четыре паттерна объясняют большинство инцидентов «как в проде», которые мы видим у арендаторов Mac-облака; таблица ниже сжимает их в первые действия.

3. Матрица «симптом — первопричина»

Используйте таблицу как шпаргалку во время инцидента. Выберите ближайший симптом, выполните колонку «первые действия» до перехода ко вторым гипотезам.

Наблюдаемый сигналВероятная первопричинаПервые действия (по порядку)
Цикл перезапусков, OOMKilled, exit 137Давление по памяти cgroup или хостаПоднять лимит памяти Docker Desktop/Engine или mem_limit в compose; остановить конкурирующие RAM-задачи; повторить сборку с меньшим параллелизмом слоёв
Permission denied на путях конфига или workspaceBind-mount с неверным владельцем uidНа хосте: sudo chown -R 1000:1000 /path/to/mount; проверить RW в compose; подтвердить docker exec -u node … touch тестовым файлом
Сбои HTTPS или DNS только внутри контейнераРезолвер контейнера или отсутствие proxy envdocker exec cat /etc/resolv.conf, curl -v; добавить dns: в compose или daemon.json; передать --env-file для корпоративных прокси
Процесс жив, но порт недоступен удалённоПроброс порта, bind-адрес или security group облакаСравнить ports: с задуманным 0.0.0.0 против 127.0.0.1; открыть правило SG; по гайдам по hardening предпочесть SSH-туннель
openclaw doctor ругается на отсутствие credentials, хотя compose «их задаёт»Переменные окружения не попали в PID контейнераdocker exec … env | grep OPENCLAW против блока environment в compose; исправить кавычки и наследование

4. Шесть упорядоченных шагов устранения (не переставляйте без причины)

Порядок важен: последующие шаги предполагают, что предыдущие уже отсекли целые классы отказов. Прыжок сразу к ретегам образа уничтожает улики.

  1. Зафиксировать состояние: Выполнить docker compose ps -a, затем docker logs <service> --tail 200. Сохранить, был ли exit 137 при pull образа, сборке или в стабильном run.
  2. Проверить запас по памяти: Временно выделить Docker порядка 4–8 ГБ для сборок (уточнить по документации провайдера). На хосте смотреть memory_pressure или аналоги Activity Monitor; тяжёлый swap плюс нагрузка шлюза — рецепт нестабильного SIGKILL.
  3. Нормализовать владение томами: Применить chown ко всем bind-путям, куда контейнер пишет. Перед возвращением к OpenClaw снова выполнить тривиальный тест записи от uid 1000 внутри контейнера.
  4. Доказать сеть из контейнера: Изнутри обратиться к провайдеру LLM через curl -sI или openssl s_client, если подозрительно TLS. При корпоративном MITM зеркалировать те же доверенные материалы или proxy-переменные, что на хосте.
  5. Запустить диагностический CLI: Выполнить openclaw doctor, openclaw status и openclaw models status (имена по актуальному CLI). Переустановку или смену тега образа — только если doctor остаётся красным с ошибками уровня установки после всего вышеперечисленного.
  6. Приёмка на порту 18789: curl -sI http://127.0.0.1:18789 (или сопоставленный порт) с хоста; для удалённых админов проверить SSH-туннель или пути reverse proxy из статей по безопасности.
docker compose ps -a docker logs openclaw-gateway-1 --tail 200 docker exec -it openclaw-gateway-1 sh -lc "id && ls -la /home/node/.openclaw && openclaw doctor"
Предупреждение: не применяйте агрессивный docker system prune -a, пока инцидент открыт — он удаляет кэш слоёв и контекст логов и увеличивает среднее время восстановления.

5. Технические факты для цитирования (минимум три — перечисляем семь)

6. Заключение: удобство Docker против нативного macOS на VPSMAC

Docker отлично подходит для воспроизводимых демо и изоляции мультитенантности, но каждый namespace и cgroup — ещё один прыжок, когда в полночь зовут на инцидент. Вы платите дублированием настроек DNS, акробатикой с uid на томах и худшей корреляцией между давлением swap на хосте и «смертельными спиралями» контейнера. Когда команды крутят образы вместо починки монтирований, накапливаются «снежинковые» compose-файлы, которые никто не хочет трогать — слабый исход для шлюза агента 7×24.

Нативная установка на bare-metal узле Mac-облака — SSH, официальный путь без контейнера, супервизия через launchd — схлопывает несколько областей отказа: тот же uid, что в ssh, пишет конфиг, настройки резолвера совпадают с вашей оболочкой, а openclaw doctor читает ту файловую систему, которой вы уже доверяете. Для нагрузок OpenClaw как для прод-сервисов, а не одноразовой лаборатории, такое уменьшение движущихся частей обычно выигрывает у очередного кастомного образа. Стеки «только Docker» добавляют постоянные накладные расходы на отладку и разброс производительности под длительной нагрузкой; выделенные физические Mac-хосты смягчают оба эффекта.

Аренда узла VPSMAC — прагматичный следующий шаг, когда триада готовности отказывается стабилизироваться: вы сохраняете совместимость с Apple Silicon и питание 24/7 без борьбы с эргономикой контейнеров поверх облачных квот. Сочтите узел со статьёй про развёртывание за пять минут для bootstrap и чеклистом прод-hardening для экспозиции — тот же toolchain, меньше «налога абстракций». Именно такой обмен рекомендует эта статья после честного исчерпания матрицы выше: не как лозунг, а потому что повторяющиеся циклы 137 и прав указывают на число слоёв, а не на качество модели.