2026‑04‑28 · OpenClaw, launchd KeepAlive, коды выхода, ThrottleInterval и триаж перезапусков / crash‑loop на headless арендованном облачном Mac (HK / JP / KR / SG / US)
Большинство продакшен‑установок OpenClaw на Mac mini M4 доступны только по SSH, с обратным прокси на 127.0.0.1 и JSON‑логами, которые удобно смотреть через структурированное логирование. Когда процесс шлюза ведёт launchd, типичный сбой — не загадка LLM, а частый перезапуск задачи после выхода: иногда это штатно (вы просили launchd всегда держать процесс), иногда катастрофа (плохой конфиг, нет PATH, падение до первого bind). Этот материал от 2026‑04‑28 связывает HTTP‑нагрузку на провайдера и обратное давление вебхуков с локальным супервизором процессов: как взаимодействуют KeepAlive и ThrottleInterval, как читать первые строки сбоя в StandardError при шумных респавнах и когда выгрузить LaunchAgent, чтобы воспроизвести в интерактивной оболочке. Дополняет рассказ о секретах в окружении и launchd и сценарий обновления в openclaw doctor и allowlist.
На headless облачном Mac launchd — ваш init
В отличие от ноутбука, никто не смотрит в Terminal, когда npm или openclaw gateway завершаются. Устойчивый шаблон: отдельная учётная запись сервиса, логи в ротируемые файлы, жизненный цикл за launchd. Частая ошибка 2026 года — сравнивать macOS с Linux‑systemd один в один: ключи вроде KeepAlive и RunAtLoad мощные и требуют явного дросселирования, иначе из опечатки на две секунды получаются тысячи событий execve в час — забитые ~/Library/Logs и удалённый шиппер логов. Воспринимайте выход процесса как первоклассный сигнал, а не как «опять упало, ну ладно».
- User LaunchAgents —
~/Library/LaunchAgentsдля долгоживущих служб на пользователя; большинство установок OpenClaw здесь ради минимальных привилегий. - System LaunchDaemons — нужны права администратора и шире зона поражения; избегайте, если действительно не нужен root.
KeepAlive: какой вариант вы включили?
Property list для KeepAlive у Apple бывает булевым или словарём с условными причинами (сеть, путь и т.д.). Булево true — кувалда: перезапуск при любом завершении процесса — то, что нужно сетевому демону 24/7, но не разовой миграции. Тоньше: NetworkState или путь, который должен существовать. Разбирая «почему перезапускается?», сначала выясните: я просил launchd держать процесс живым, или приложение само выходит и выход ≠ краш? Чистый exit 0 при KeepAlive true всё равно вызывает рестарт — как при обёртке, которая завершается, если дочерний процесс отцепили неправильно.
ThrottleInterval до секунды, «молоток» — супервизор; если флап без ритма — подозревайте необработанные отказы промисов или гонку bind порта, а не LLM.
StandardOut / StandardError: настоящие файлы
Сессии SSH без GUI не TTY; stdio «в никуда» — способ потерять первые 200 мс краша. Укажите StandardOutPath и StandardErrorPath в каталог, куда сервисный пользователь может писать, ротируйте через newsyslog macOS или простой ежедневный cron, и никогда не полагайтесь на буфер интерактивной оболочки. При корреляции с инцидентами исходящего трафика и TLS один срез по времени между stdout, access‑логом nginx и JSON шлюза ценнее красивой Grafana.
ThrottleInterval: тормоз перед рестартом
ThrottleInterval — минимум секунд ожидания после выхода, прежде чем launchd сможет перезапустить задачу. Ставьте 10, если при первом запуске нужны спокойные логи, 1–2 в стационаре, когда хотите пережить временные блокировки без дежурных. В паре: launchctl print gui/$(id -u)/com.example.openclaw (домен пользователя, подставьте label) — читать состояние и последний exit. Зафиксируйте число в плейбуке: «при Throttle=10 в худшем случае не чаще одного рестарта за 10 с» — так выравниваете ожидания, когда просят MTTR < 1 мин для софта, а не для инфраструктуры.
openclaw doctor может быть зелёным, пока launchd в crash‑loop: doctor — интерактивный короткий запуск с полным login‑окружением; в plist может не хватать PATH для node или глобального префикса npm. Всегда сравнивайте env | sort с выводом doctor.
Коды выхода, которые реально попадают в тикеты
| Выход / симптом | Вероятная причина OpenClaw | Сначала сделать |
|---|---|---|
1 (общий) + один стек в stderr |
Разбор конфига, нет переменной OPENCLAW_, неверный cwd |
Те же ProgramArguments по SSH с set -a; source your.env; set +a по шаблону секретов. |
2 (misuse) от shell‑обёртки |
Разбор опций или кавычки путей на Mac | Логировать сырой argv в обёртке, избегать glob, убедиться, что Node не под Rosetta для arm64 (профили SSH). |
126 / 127 |
Не исполняемый файл или node не в PATH plist |
Абсолютный путь к бинарнику, which -a node в контексте сервиса. |
| Сигнал 9 / exit 137 (жаргон Linux) — на macOS часто жёсткий kill | OOM, ручной kill или (редко) watchdog — на M4 смотрите память LLM и шлюза вместе | memory pressure в Console или снижайте параллелизм по ограничению провайдера. |
Триаж crash‑loop: шесть вопросов до смены модели
- Порт занят? Лишний шлюз или зомби‑слушатель ломают bind — см. nginx reverse proxy и согласование портов.
- Exit 0 в цикле? Обёртка с exit 0 всё равно может триггерить
KeepAlive, если не сделалиexecв дочерний процесс. - stderr каждый раз одинаковый? Одна и та же строка → детерминированный конфиг; меняющийся стек → гонка или сетевой флейк.
- Что меняли в последний раз? Привязывайте к git‑тегу или lockfile
npm; культура дисциплины релиза помогает и без App Store. - Upstream отдаёт 401, а retry не кончается? Нужен circuit breaker, а не больше давления
KeepAlive— см. 429/503 в лимитах LLM. - Дроссель на «молоток» есть? Если нет, первый «фикс» часто просто
ThrottleInterval, чтобы прочитать логи, потом правка конфига/кода.
log stream --style compact --predicate 'process == "openclaw"' только после снижения частоты рестартов — иначе шум спрячет нужную первую строку.
Операционный чек‑лист plist (Confluence / Notion)
- Label — уникальный reverse‑DNS; не переиспользуйте чужой префикс
com.при той жеUID. - ProgramArguments[0] — полный путь, без сюрпризов от login‑shell.
- WorkingDirectory — корень репозитория для относительных путей конфига; согласовано с
openclaw doctor. - EnvironmentVariables —
HOME,PATH, при необходимостиNODE_OPTIONS— в линию с докой по секретам. - KeepAlive + ThrottleInterval — не сочетайте агрессивный рестарт с крошечным лимитом stderr без ротации.
plutil -lint ~/Library/LaunchAgents/com.yourorg.openclaw.plist
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.yourorg.openclaw.plist
Семь ops‑шагов, когда страница пишет «OpenClaw в SG лежит»
- Здоровье края (nginx) — 502 против 504 отделяет upstream от шлюза; при сбое исходящего трафика проверьте DNS / TLS.
- Состояние launchd —
launchctl printпо label; последний exit и окна throttle. - Стабилизировать логи — при флапе
ThrottleInterval. - Интерактивное воспроизведение под той же
UIDбезlaunchd. - Diff конфига и ротация секретов с ревью вдвоём.
- Roll forward на известную хорошую версию
npm, не тайный патч в проде. - Post‑incident — абзац в тикете: причина, пробел в детекции, защита (например алерт при exit ≠ 0 за минуту).
FAQ: launchd против самого шлюза OpenClaw
| Вопрос | Ответ на 2026‑04‑28 |
|---|---|
Ставить ProcessType в Interactive? |
Для серверного демона обычно нет; Interactive меняет приоритеты планировщика. Обычный фон, если документация Apple для вашей сборки macOS не говорит иначе для класса нагрузки. |
Нужен ли caffeinate? |
На арендованном 24/7 Mac mini M4 в дата‑центре сон обычно отключён политикой питания; на ноут‑хостах (не случай MacXCode) caffeinate не лечит краш после пробуждения. |
Почему Apple Silicon Mac mini M4 всё ещё в этом runbook
launchd ровно настолько честен, насколько железо под ним. Bare‑metal Mac mini M4 в Гонконге, Токио, Сеуле, Сингапуре или США с 1–2 ТБ и предсказуемым планированием CPU превращает вопрос «мы уперлись по памяти шлюза из‑за tool‑calls?» в измеримый, а не про «ощущения». Те же ядра с хорошей поддержкой MPS для локальных ML‑экспериментов дают запас на структурные шипперы логов, reverse‑proxy и стек OpenClaw на одну биллинговую единицу — поэтому команды читают такие статьи вместе со страницей тарифов по регионам и руководством по доступу, когда одного ноутбука уже мало.
Запускайте OpenClaw там, где launchd, логи и сеть сходятся
1–2 ТБ · Apple Silicon · SSH / опционально VNC