Hosting
Fly.io
Цель: Gateway OpenClaw, работающий на машине Fly.io с постоянным хранилищем, автоматическим HTTPS и доступом через Discord/каналы.
Что потребуется
- Установленный CLI flyctl
- Учетная запись Fly.io (подойдет бесплатный тариф)
- Аутентификация модели: ключ API выбранного поставщика модели
- Учетные данные каналов: токен бота Discord, токен Telegram и т. д.
Быстрый путь для начинающих
- Клонируйте репозиторий, настройте
fly.toml - Создайте приложение и том, задайте секреты
- Разверните с помощью
fly deploy - Подключитесь по SSH, чтобы создать конфигурацию, или используйте интерфейс управления
Создайте приложение Fly
git clone https://github.com/openclaw/openclaw.gitcd openclaw # выберите собственное имяfly apps create my-openclaw # обычно достаточно 1 ГБfly volumes create openclaw_data --size 1 --region iadВыберите ближайший к вам регион. Распространенные варианты: lhr (Лондон), iad (Вирджиния), sjc (Сан-Хосе).
Настройте fly.toml
Отредактируйте fly.toml в соответствии с именем приложения и вашими требованиями. Отслеживаемый в репозитории файл fly.toml — это показанный ниже общедоступный шаблон; deploy/fly.private.toml — усиленный вариант без общедоступного IP-адреса (см. Закрытое развертывание).
app = "my-openclaw" # имя вашего приложенияprimary_region = "iad" [build] dockerfile = "Dockerfile" [env] NODE_ENV = "production" OPENCLAW_PREFER_PNPM = "1" OPENCLAW_STATE_DIR = "/data" NODE_OPTIONS = "--max-old-space-size=1536" [processes] app = "node dist/index.js gateway --allow-unconfigured --port 3000 --bind lan" [http_service] internal_port = 3000 force_https = true auto_stop_machines = false auto_start_machines = true min_machines_running = 1 processes = ["app"] [[vm]] size = "shared-cpu-2x" memory = "2048mb" [mounts] source = "openclaw_data" destination = "/data"Точкой входа Docker-образа OpenClaw служит tini, которая по умолчанию запускает node openclaw.mjs gateway. Fly [processes] заменяет Docker CMD (здесь он напрямую запускает node dist/index.js gateway ..., ту же скомпилированную точку входа), не затрагивая ENTRYPOINT, поэтому процесс по-прежнему выполняется от имени tini.
Основные параметры:
| Параметр | Назначение |
|---|---|
--bind lan |
Привязывается к 0.0.0.0, чтобы прокси Fly мог обращаться к Gateway |
--allow-unconfigured |
Запускается без файла конфигурации (вы создадите его позже) |
internal_port = 3000 |
Должен совпадать с --port 3000 (или OPENCLAW_GATEWAY_PORT) для проверок работоспособности Fly |
memory = "2048mb" |
512 МБ недостаточно; рекомендуется 2 ГБ |
OPENCLAW_STATE_DIR = "/data" |
Сохраняет состояние на томе |
Задайте секреты
# обязательно: токен аутентификации Gateway для привязки не к loopback-интерфейсуfly secrets set OPENCLAW_GATEWAY_TOKEN=$(openssl rand -hex 32) # ключи API поставщиков моделейfly secrets set ANTHROPIC_API_KEY=example-anthropic-key-not-real # необязательно: другие поставщикиfly secrets set OPENAI_API_KEY=example-openai-key-not-realfly secrets set GOOGLE_API_KEY=... # токены каналовfly secrets set DISCORD_BOT_TOKEN=example-discord-bot-tokenДля привязок не к loopback-интерфейсу (--bind lan) требуется действующий способ аутентификации Gateway. В этом примере используется OPENCLAW_GATEWAY_TOKEN, но требованию также удовлетворяет gateway.auth.password или правильно настроенное развертывание с доверенным прокси и привязкой не к loopback-интерфейсу. Контракт SecretRef описан в разделе Управление секретами.
Обращайтесь с этими токенами как с паролями. Для ключей API и токенов предпочитайте переменные среды/fly secrets файлу конфигурации, чтобы секреты не попадали в openclaw.json.
Разверните
fly deployПри первом развертывании создается Docker-образ. После развертывания выполните проверку:
fly statusfly logsПосле запуска HTTP/WebSocket-прослушивателя Gateway записывает в журнал gateway ready. Собственная проверка работоспособности Fly отслеживает internal_port = 3000 согласно fly.toml; директива Docker HEALTHCHECK образа дополнительно опрашивает /healthz на порте по умолчанию 18789, который здесь не используется, поскольку в этом развертывании порт Gateway переопределен на --port 3000.
Создайте файл конфигурации
Подключитесь к машине по SSH, чтобы создать правильную конфигурацию:
fly ssh consolemkdir -p /datacat > /data/openclaw.json << 'EOF'{ "agents": { "defaults": { "model": { "primary": "anthropic/claude-opus-4-6", "fallbacks": ["anthropic/claude-sonnet-4-6", "openai/gpt-5.4"] }, "maxConcurrent": 4 }, "list": [ { "id": "main", "default": true } ] }, "auth": { "profiles": { "anthropic:default": { "mode": "token", "provider": "anthropic" }, "openai:default": { "mode": "token", "provider": "openai" } } }, "bindings": [ { "agentId": "main", "match": { "channel": "discord" } } ], "channels": { "discord": { "enabled": true, "groupPolicy": "allowlist", "guilds": { "YOUR_GUILD_ID": { "channels": { "general": { "allow": true } }, "requireMention": false } } } }, "gateway": { "mode": "local", "bind": "auto", "controlUi": { "allowedOrigins": [ "https://my-openclaw.fly.dev", "http://localhost:3000", "http://127.0.0.1:3000" ] } }, "meta": {}}EOFПри OPENCLAW_STATE_DIR=/data путь к конфигурации — /data/openclaw.json.
Замените https://my-openclaw.fly.dev реальным источником приложения Fly. При запуске Gateway локальные источники интерфейса управления инициализируются значениями среды выполнения --bind и --port, чтобы первая загрузка могла пройти до создания конфигурации, однако для доступа из браузера через Fly по-прежнему необходимо указать точный источник HTTPS в gateway.controlUi.allowedOrigins.
Токен Discord можно получить одним из следующих способов:
- Переменная среды
DISCORD_BOT_TOKEN(рекомендуется для секретов); добавлять ее в конфигурацию не требуется — Gateway считывает ее автоматически - Файл конфигурации
channels.discord.token
Перезапустите, чтобы применить изменения:
exitfly machine restart <machine-id>Получите доступ к Gateway
Интерфейс управления
fly openИли откройте https://my-openclaw.fly.dev/.
Выполните аутентификацию с помощью настроенного общего секрета: токена Gateway из OPENCLAW_GATEWAY_TOKEN или пароля, если вы перешли на аутентификацию по паролю.
Журналы
fly logs # журналы в реальном времениfly logs --no-tail # последние журналыКонсоль SSH
fly ssh consoleУстранение неполадок
«Приложение не прослушивает ожидаемый адрес»
Gateway привязан к 127.0.0.1 вместо 0.0.0.0.
Исправление: добавьте --bind lan в команду процесса в fly.toml.
Проверки работоспособности завершаются с ошибкой / в подключении отказано
Fly не может обратиться к Gateway через настроенный порт.
Исправление: убедитесь, что internal_port соответствует порту Gateway (--port 3000 или OPENCLAW_GATEWAY_PORT=3000).
OOM / проблемы с памятью
Контейнер постоянно перезапускается или принудительно завершается. Признаки: SIGABRT, v8::internal::Runtime_AllocateInYoungGeneration или перезапуски без сообщений.
Исправление: увеличьте объем памяти в fly.toml:
[[vm]] memory = "2048mb"Или обновите существующую машину:
fly machine update <machine-id> --vm-memory 2048 -y512 МБ недостаточно. 1 ГБ может работать, но при нагрузке или подробном журналировании возможен OOM. Рекомендуется 2 ГБ.
Проблемы с блокировкой Gateway
После перезапуска контейнера Gateway отказывается запускаться с ошибками «уже запущен».
Файлы блокировки среды выполнения находятся в <tmpdir>/openclaw-<uid>/gateway.<hash>.lock
и gateway.state.<hash>.lock (Linux:
/tmp/openclaw-<uid>/gateway.*.lock), а не на постоянном томе /data, поэтому
при полном перезапуске контейнера они обычно удаляются вместе с остальной
файловой системой контейнера. Если блокировка сохраняется (например, при fly machine restart,
который сохраняет файловую систему контейнера) и препятствует запуску, удалите ее
вручную:
fly ssh console --command "rm -f /tmp/openclaw-*/gateway.*.lock"fly machine restart <machine-id>Конфигурация не считывается
--allow-unconfigured только обходит проверку при запуске. Этот параметр не создает и не исправляет /data/openclaw.json, поэтому убедитесь, что реальная конфигурация существует и содержит "gateway": { "mode": "local" } для обычного запуска локального Gateway.
Убедитесь, что конфигурация существует:
fly ssh console --command "cat /data/openclaw.json"Запись конфигурации через SSH
fly ssh console -C не поддерживает перенаправление оболочки. Чтобы записать файл конфигурации:
# echo + tee (передача по каналу с локальной машины на удаленную)echo '{"your":"config"}' | fly ssh console -C "tee /data/openclaw.json" # или sftpfly sftp shell> put /local/path/config.json /data/openclaw.jsonfly sftp может завершиться с ошибкой, если файл уже существует; сначала удалите его:
fly ssh console --command "rm /data/openclaw.json"Состояние не сохраняется
Если после перезапуска исчезают профили аутентификации, состояние каналов/поставщиков или сеансы, каталог состояния записывается в файловую систему контейнера, а не на том.
Исправление: убедитесь, что OPENCLAW_STATE_DIR=/data задан в fly.toml, и повторите развертывание.
Обновление
git pullfly deployfly statusfly logsgit pull + fly deploy — контролируемый способ обновления в этом случае: он заново собирает образ из Dockerfile, поэтому версия CLI/Gateway, базовый образ ОС и все изменения Dockerfile обновляются вместе. openclaw update внутри работающего контейнера выполняет другую операцию, поскольку образ поставляется в виде созданного Docker дерева dist/ без рабочей копии .git и без глобальной установки под управлением npm, которую эта команда могла бы обнаружить; соответствующий процесс для установок в стиле виртуальной машины описан в разделе Обновление.
Обновление команды машины
Чтобы изменить команду запуска без полного повторного развертывания:
fly machines listfly machine update <machine-id> --command "node dist/index.js gateway --port 3000 --bind lan" -y # или с увеличением объема памятиfly machine update <machine-id> --vm-memory 2048 --command "node dist/index.js gateway --port 3000 --bind lan" -yПоследующий fly deploy сбрасывает команду машины до значения из fly.toml; после повторного развертывания примените изменения вручную еще раз.
Закрытое развертывание (усиленное)
По умолчанию Fly выделяет общедоступные IP-адреса, поэтому ваш Gateway доступен по адресу https://your-app.fly.dev и может быть обнаружен интернет-сканерами (Shodan, Censys и т. д.).
Используйте deploy/fly.private.toml для усиленного развертывания без общедоступного IP-адреса: этот вариант не содержит [http_service], поэтому общедоступный входящий доступ не выделяется.
Когда использовать закрытое развертывание
- Только исходящие вызовы/сообщения (без входящих Webhook)
- Туннели ngrok или Tailscale обрабатывают все обратные вызовы Webhook
- Доступ к Gateway выполняется через SSH, прокси или WireGuard, а не через браузер
- Развертывание должно быть скрыто от интернет-сканеров
Настройка
fly deploy -c deploy/fly.private.tomlИли преобразуйте существующее развертывание:
# вывести текущие IP-адресаfly ips list -a my-openclaw # освободить публичные IP-адресаfly ips release <public-ipv4> -a my-openclawfly ips release <public-ipv6> -a my-openclaw # переключиться на приватную конфигурацию, чтобы при последующих развертываниях публичные IP-адреса не выделялись повторноfly deploy -c deploy/fly.private.toml # выделить только приватный IPv6-адресfly ips allocate-v6 --private -a my-openclawПосле этого fly ips list должна отображать только IP-адрес типа private:
ВЕРСИЯ IP ТИП РЕГИОНv6 fdaa:x:x:x:x::x приватный глобальныйДоступ к приватному развертыванию
Вариант 1: локальный прокси (самый простой)
fly proxy 3000:3000 -a my-openclaw# открыть http://localhost:3000 в браузереВариант 2: VPN WireGuard
fly wireguard create# импортировать в клиент WireGuard, затем получить доступ через внутренний IPv6-адрес# пример: http://[fdaa:x:x:x:x::x]:3000Вариант 3: только SSH
fly ssh console -a my-openclawWebhook при приватном развертывании
Для обратных вызовов Webhook (Twilio, Telnyx и т. д.) без публичного доступа:
- туннель ngrok: запустите ngrok внутри контейнера или как вспомогательный контейнер
- Tailscale Funnel: предоставьте доступ к определенным путям через Tailscale
- Только исходящие подключения: некоторые провайдеры (Twilio) поддерживают исходящие вызовы без Webhook
Пример конфигурации голосовых вызовов с ngrok в разделе plugins.entries.voice-call.config:
{ plugins: { entries: { "voice-call": { enabled: true, config: { provider: "twilio", tunnel: { provider: "ngrok" }, webhookSecurity: { allowedHosts: ["example.ngrok.app"], }, }, }, }, },}Туннель ngrok работает внутри контейнера и предоставляет публичный URL-адрес Webhook, не открывая публичный доступ к самому приложению Fly. Укажите имя хоста туннеля в webhookSecurity.allowedHosts, чтобы разрешить перенаправленные заголовки хоста.
Компромиссы безопасности
| Аспект | Публичное развертывание | Приватное развертывание |
|---|---|---|
| Интернет-сканеры | Обнаруживается | Скрыто |
| Прямые атаки | Возможны | Заблокированы |
| Доступ к интерфейсу управления | Через браузер | Через прокси/VPN |
| Доставка Webhook | Напрямую | Через туннель |
Примечания
- Fly.io использует архитектуру x86; Dockerfile совместим как с x86, так и с ARM.
- Для подключения WhatsApp/Telegram используйте
fly ssh console. - Постоянные данные хранятся на томе по пути
/data. - Для Signal в образе требуется signal-cli (CLI на основе Java); используйте собственный образ и выделите не менее 2GB памяти.
Стоимость
При рекомендуемой конфигурации (shared-cpu-2x, 2GB ОЗУ) ожидайте расходы примерно $10-15 в месяц в зависимости от использования; бесплатный тариф покрывает часть базового объема ресурсов. Актуальные тарифы приведены на странице цен Fly.io.
Дальнейшие действия
- Настройте каналы обмена сообщениями: Каналы
- Настройте Gateway: Конфигурация Gateway
- Поддерживайте OpenClaw в актуальном состоянии: Обновление