В пятницу вечером webhook'и внезапно краснеют. Вы заходите по SSH на удалённый Mac и видите, что процесс шлюза давно исчез — в прошлый раз вы запустили его вручную через openclaw gateway run, а после ночной перезагрузки никто не повторил команду. Discord-бот показывает «онлайн», но порт 18789 пуст, а в очереди GitHub уже 47 ответов 502.
Это не баг OpenClaw — это модель эксплуатации, застрявшая в «мышлении dev-машины»: интерактивный запуск, plist, правленный вручную, отдельная конфигурация на каждом хосте. В 2026 году шлюз нужно рассматривать как инфраструктуру, а на macOS для этого подходит launchd — автозапуск при загрузке, восстановление после сбоя, логи на диске, конфигурация в Git.
Эта статья даёт путь от нуля до приёмки: регистрация через onboard, продакшен-шаблон plist, bootstrap-скрипт в один клик, health-probe и порядок отката при обновлении. По устранению неполадок см. сопутствующий справочник по стабильности шлюза OpenClaw в launchd; по CI на нескольких машинах — OpenClaw: пошаговое развёртывание и автоматизация GitHub Actions.
Краткий ответ: три самых частых вопроса
| Вопрос | Прямой ответ | На что обратить внимание |
|---|---|---|
| Как быстрее всего пережить перезагрузку? | openclaw onboard с launchd или bootstrap-скрипт в конце статьи |
Сначала зелёный doctor, иначе получите crash loop |
Можно ли совмещать ручной gateway run и launchd? |
Нет — двойная привязка порта | Перед сменой: launchctl bootout + lsof для очистки порта |
| Как доказать, что это действительно HA? | reboot → подождать 2 минуты → gateway probe + внешний curl |
Не ограничивайтесь localhost |
1. Почему пора отказаться от ручной настройки
На удалённом постоянно включённом Mac ручная конфигурация ломается предсказуемо:
| Подход | Кажется удобным | Реальная цена |
|---|---|---|
nohup openclaw gateway run & по SSH |
Сервис за 5 секунд | Пропадает после reboot; нет ротации логов; код выхода не виден |
| Ручное редактирование plist на каждой машине | «Просто сменить порт» | Конфликты Label, дрейф PATH, нет diff при обновлении |
| В документации: «нажать Старт после входа» | Обход проблем TCC | Отключение питания в праздники → гарантированный простой |
| Docker и launchd одновременно | «Дополнительная страховка» | Борьба за 18789; двойная блокировка каталога State |
launchd берёт на себя надзор за процессом; вы сосредотачиваетесь на конфигурации и probe — вот что и есть автоматизация.
2. Что означает «высокая доступность» шлюза на Mac
Один Mac не даст HA в стиле Kubernetes с несколькими репликами, но эксплуатационную HA достичь можно:
- Survive reboot: шлюз слушает в течение 2 минут после загрузки, без ручного SSH.
- Survive crash:
KeepAlive+ThrottleInterval— аварийный выход запускает перезапуск с откатом, без загрузки CPU на 100%. - Survive config drift: plist, переменные окружения и
~/.openclawс резервными копиями и историей в Git. - Survive silent failure: внешний healthcheck ловит ситуацию «порт слушает, но probe падает».
- Survive upgrade: фиксированный порядок
backup → doctor --fix → gateway restart, каждый раз одинаковый и скриптуемый.
На практике: M4 Mac mini (24 ГБ) со шлюзом OpenClaw и лёгкими плагинами в простое потребляет около 4–6 Вт; память процесса шлюза обычно 200–450 МБ. Размещение машины по пути нативного удалённого развёртывания на Mac предсказуемее, чем оставлять iMac включённым в офисе.
3. LaunchAgent или LaunchDaemon
| Параметр | LaunchAgent (пользовательский домен) | LaunchDaemon (системный домен) |
|---|---|---|
| Путь | ~/Library/LaunchAgents/ |
/Library/LaunchDaemons/ |
| Момент запуска | После входа пользователя | При загрузке системы, без GUI-входа |
| TCC / связка ключей | Наследует разрешения пользователя | Ограничен — подходит для чистых сетевых демонов |
| Лучше всего для | Автоматизация браузера, плагины с доступом к каталогам пользователя | Чистый HTTP/Webhook-шлюз без зависимости от GUI |
Рекомендация на 2026 год: начните с LaunchAgent — прогоните через него onboard и doctor. Переходите на Daemon только после подтверждения, что сессия входа не нужна, и зафиксируйте это в runbook. В любом случае ProgramArguments должны содержать абсолютные пути — launchd не читает ваш .zshrc.
4. Регистрация launchd через onboard в один клик
Мастер onboard OpenClaw записывает путь к Node, каталог State и порт шлюза в конфигурацию, а в новых версиях поддерживает прямую установку сервиса launchd. Рекомендуемый порядок:
# 1. 确认运行时(与 plist 内 PATH 一致)
node -v # 期望 v22.x
which openclaw # 记下绝对路径,如 /opt/homebrew/bin/openclaw
# 2. 预检
openclaw doctor
# 3. 交互式 onboard(按提示启用 Gateway + launchd)
openclaw onboard
# 4. 验收
launchctl print "gui/$(id -u)/com.openclaw.gateway" 2>/dev/null || launchctl list | grep -i openclaw
lsof -nP -iTCP:18789 -sTCP:LISTEN
openclaw gateway probe
5. Продакшен-шаблон plist (готов к Git)
Если onboard не создал plist, или вам нужно явно версионировать его в infra-репозитории, используйте шаблон ниже. Замените OPENCLAW_BIN на вывод which openclaw:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.openclaw.gateway</string>
<key>ProgramArguments</key>
<array>
<string>/opt/homebrew/bin/openclaw</string>
<string>gateway</string>
<string>run</string>
</array>
<key>WorkingDirectory</key>
<string>/Users/your-ci-user</string>
<key>EnvironmentVariables</key>
<dict>
<key>PATH</key>
<string>/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin</string>
<key>HOME</key>
<string>/Users/your-ci-user</string>
</dict>
<key>StandardOutPath</key>
<string>/Users/your-ci-user/Library/Logs/OpenClawGateway/gateway.stdout.log</string>
<key>StandardErrorPath</key>
<string>/Users/your-ci-user/Library/Logs/OpenClawGateway/gateway.stderr.log</string>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<dict>
<key>SuccessfulExit</key>
<false/>
</dict>
<key>ThrottleInterval</key>
<integer>30</integer>
</dict>
</plist>
Загрузка (Ventura+):
UID_NUM=$(id -u)
DOMAIN="gui/${UID_NUM}"
LABEL="com.openclaw.gateway"
PLIST="${HOME}/Library/LaunchAgents/${LABEL}.plist"
launchctl bootout "${DOMAIN}/${LABEL}" 2>/dev/null || true
launchctl bootstrap "${DOMAIN}" "${PLIST}"
launchctl kickstart -k "${DOMAIN}/${LABEL}"
Типичные ошибки:
- На Intel Mac Homebrew часто в
/usr/local/bin, на Apple Silicon — в/opt/homebrew/bin; пропишите в plist явно, а не «универсальный PATH». - Сначала
mkdir -pдля каталога логов — иначе launchd может не стартовать, а stderr некуда писать. - Не держите один и тот же Label одновременно в пользовательском и системном домене; перед обновлением выполните
bootoutстарой задачи.
6. Bootstrap-скрипт в один клик
Объедините «установить CLI → doctor → записать plist → bootstrap → probe» в одну команду — удобно для только что арендованного облачного Mac или self-hosted runner GitHub Actions. Полный скрипт в каталоге ресурсов этой статьи:
resources/bootstrap-openclaw-gateway-launchd.sh
На удалённом Mac:
chmod +x bootstrap-openclaw-gateway-launchd.sh
./bootstrap-openclaw-gateway-launchd.sh
Краткая логика скрипта:
- Проверка
node/openclaw; при отсутствии —npm i -g openclaw@latest - Создание
~/Library/Logs/OpenClawGateway - Приоритет
openclaw onboard; если plist нет — запись резервного LaunchAgent launchctl bootstrap+kickstart -k- Приёмка через
lsof+openclaw gateway probe
7. Health-probe и внешнее самовосстановление
KeepAlive проверяет только наличие процесса, но не ситуацию «процесс завис, а порт всё ещё LISTEN». Добавьте лёгкий probe LaunchAgent (каждые 5 минут):
#!/bin/bash
# ~/bin/openclaw-gateway-healthcheck.sh
set -euo pipefail
PORT="${OPENCLAW_GATEWAY_PORT:-18789}"
LABEL="com.openclaw.gateway"
DOMAIN="gui/$(id -u)"
if ! openclaw gateway probe >/dev/null 2>&1; then
logger -t openclaw-ha "probe failed, kickstart gateway"
launchctl kickstart -k "${DOMAIN}/${LABEL}" || true
fi
Свяжите с plist через StartCalendarInterval в ~/Library/LaunchAgents/com.openclaw.gateway-healthcheck.plist. Можно подключить UptimeRobot или Prometheus blackbox exporter — но probe должен идти тем же путём, что и webhook'и (с reverse proxy и TLS), а не только curl localhost.
Ротируйте логи через newsyslog или усечение по размеру, чтобы один файл не заполнил NVMe — при переполнении диска дочерние процессы launchd выходят с ENOSPC, и это выглядит как «случайные обрывы».
8. Конфигурация в Git и поэтапные обновления
Храните в версионном контроле и ревьюйте в PR, а не правьте по SSH:
| Файл | Назначение |
|---|---|
launchagents/com.openclaw.gateway.plist |
Основной сервис шлюза |
scripts/bootstrap-openclaw-gateway-launchd.sh |
Настройка нового узла |
scripts/upgrade-openclaw-gateway.sh |
Фиксированная последовательность обновления |
docs/runbook-gateway.md |
Справочник для дежурного |
Минимальный порядок скрипта обновления (согласован со статьёй о многоканальной стабильности шлюза):
openclaw backup create
npm update -g openclaw@latest # 或锁版本号
openclaw doctor --fix
launchctl kickstart -k "gui/$(id -u)/com.openclaw.gateway"
openclaw gateway probe
# 多插件环境:逐个 browser/cron doctor
9. Семишаговый чеклист приёмки
Перед релизом или выводом новой машины в прод зайдите по SSH и отметьте:
openclaw doctorбез ERRORlaunchctl print gui/$(id -u)/com.openclaw.gatewayв состоянии runninglsof -nP -iTCP:18789 -sTCP:LISTEN— PID совпадает с plistopenclaw gateway probeуспешен- curl публичной точки входа из офисной сети / мобильного интернета (не только 127.0.0.1)
- После
sudo rebootprobe снова успешен в течение 2 минут - Намеренный
killPID шлюза — автовосстановление за 30 секунд без спама Throttle
10. Почему для этой автоматизации по-прежнему лучше Mac mini
Шлюзу нужны постоянная работа, тишина и единые пути. Mac mini M4 на Apple Silicon в простое потребляет около 4 Вт — круглосуточная работа на порядок дешевле настольного ПК. launchd, Homebrew и ~/.openclaw OpenClaw совпадают с локальной dev-машиной, поэтому не придётся вести два runbook.
Если вы переносите OpenClaw с «эксперимента на ноутбуке» на выделенный удалённый Mac, сначала отладьте автоматизацию на одном узле, затем добавляйте ноды. На главной Macstripe можно взять Mac mini с посуточной оплатой в разных регионах — один раз прогоните bootstrap, и это удобнее, чем держать машину включённой в офисе.
FAQ
Обязательно ли использовать launchd для шлюза OpenClaw?
Нет — но на macOS launchd — официальный менеджер демонов, и для работы без присмотра он подходит лучше, чем nohup. Docker удобен для параллельных версий; launchd — для шлюза с меньшей задержкой и без лишней виртуализации.
Что выбрать — LaunchAgent или LaunchDaemon?
LaunchAgent — если нужны TCC пользователя или связка ключей; LaunchDaemon (root) — если сервис должен слушать без входа в систему. Большинство команд начинают с Agent.
Конфликтует ли onboard с plist, написанным вручную?
Label должен быть уникальным. Перед обновлением выполните bootout, чтобы два процесса не боролись за 18789. Финальный plist лучше хранить в Git.
Probe падает, но порт слушает?
Проверьте аутентификацию, TLS и адрес привязки. Выполните doctor, затем сверьте ~/.openclaw; подробности — в справочнике по устранению неполадок launchd.
Как развернуть на нескольких Mac?
Self-hosted runner'ы + один bootstrap-скрипт, secrets для токенов, поэтапная приёмка через probe. См. совместную работу нескольких runner в GitHub Actions.
Итог
Хватит настраивать вручную — не значит «никогда не открывать терминал», а значит в терминале только скрипты, никаких импровизаций: onboard регистрирует launchd, plist уходит в Git, bootstrap настраивает новые машины, probe принимает, healthcheck страхует краевые случаи. Шлюз перестаёт быть «процессом на переднем плане в SSH-сессии» и становится повторяемой инфраструктурой.
Следующий шаг: прогоните bootstrap на одном удалённом Mac, сделайте учебную перезагрузку и вставьте семишаговый чеклист в wiki команды. Когда понадобится выделенный узел — выберите регион на главной Macstripe.