Развертывание на Fly.io
Цель: OpenClaw Gateway, работающий на машине Fly.io с постоянным хранилищем, автоматическим HTTPS и доступом к Discord/каналам.
Что вам понадобится
- Установленный flyctl CLI
- Аккаунт Fly.io (бесплатный тариф работает)
- Аутентификация модели: API-ключ Anthropic (или ключи других провайдеров)
- Учетные данные канала: токен Discord-бота, токен Telegram и т.д.
Быстрый путь для начинающих
- Клонировать репозиторий → настроить fly.toml
- Создать приложение + том → установить секреты
- Развернуть с помощью fly deploy
- SSH для создания конфигурации или использовать Control UI
1) Создать приложение Fly
# Клонировать репозиторий
git clone https://github.com/openclaw/openclaw.git
cd openclaw
# Создать новое приложение Fly (выберите свое имя)
fly apps create my-openclaw
# Создать постоянный том (обычно достаточно 1GB)
fly volumes create openclaw_data --size 1 --region iad
Совет: Выберите регион ближе к вам. Распространенные варианты: lhr (Лондон), iad (Вирджиния), sjc (Сан-Хосе).
2) Настроить fly.toml
Отредактируйте fly.toml в соответствии с названием вашего приложения и требованиями.
Примечание по безопасности: Конфигурация по умолчанию предоставляет публичный URL. Для защищенного развертывания без публичного IP см. Приватное развертывание или используйте fly.private.toml.
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"
Ключевые настройки:
| Настройка | Зачем |
|---|---|
| --bind lan | Привязывается к 0.0.0.0, чтобы прокси Fly мог достичь gateway |
| --allow-unconfigured | Запускается без файла конфигурации (вы создадите его после) |
| internal_port = 3000 | Должен соответствовать --port 3000 (или OPENCLAW_GATEWAY_PORT) для проверок здоровья Fly |
| memory = "2048mb" | 512MB слишком мало; рекомендуется 2GB |
| OPENCLAW_STATE_DIR = "/data" | Сохраняет состояние на томе |
3) Установить секреты
# Обязательно: токен Gateway (для не-loopback привязки)
fly secrets set OPENCLAW_GATEWAY_TOKEN=$(openssl rand -hex 32)
# API-ключи провайдера модели
fly secrets set ANTHROPIC_API_KEY=sk-ant-...
# Опционально: другие провайдеры
fly secrets set OPENAI_API_KEY=sk-...
fly secrets set GOOGLE_API_KEY=...
# Токены каналов
fly secrets set DISCORD_BOT_TOKEN=MTQ...
Примечания:
- Не-loopback привязки (--bind lan) требуют OPENCLAW_GATEWAY_TOKEN для безопасности.
- Относитесь к этим токенам как к паролям.
- Предпочитайте переменные окружения вместо конфигурационного файла для всех API-ключей и токенов. Это не позволяет секретам попасть в openclaw.json, где они могут быть случайно раскрыты или залогированы.
4) Развернуть
fly deploy
Первое развертывание собирает Docker-образ (~2-3 минуты). Последующие развертывания быстрее.
После развертывания проверьте:
fly status
fly logs
Вы должны увидеть:
[gateway] listening on ws://0.0.0.0:3000 (PID xxx)
[discord] logged in to discord as xxx
5) Создать файл конфигурации
SSH в машину для создания правильной конфигурации:
fly ssh console
Создайте директорию конфигурации и файл:
mkdir -p /data
cat > /data/openclaw.json << 'EOF'
{
"agents": {
"defaults": {
"model": {
"primary": "anthropic/claude-opus-4-5",
"fallbacks": ["anthropic/claude-sonnet-4-5", "openai/gpt-4o"]
},
"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"
},
"meta": {
"lastTouchedVersion": "2026.1.29"
}
}
EOF
Примечание: С OPENCLAW_STATE_DIR=/data путь конфигурации — /data/openclaw.json.
Примечание: Токен Discord может быть из:
- Переменная окружения: DISCORD_BOT_TOKEN (рекомендуется для секретов)
- Файл конфигурации: channels.discord.token
Если используется переменная окружения, не нужно добавлять токен в конфигурацию. Gateway автоматически читает DISCORD_BOT_TOKEN.
Перезапустите для применения:
exit
fly machine restart <machine-id>
6) Доступ к Gateway
Control UI
Откройте в браузере:
fly open
Или посетите https://my-openclaw.fly.dev/
Вставьте токен gateway (тот, что из OPENCLAW_GATEWAY_TOKEN) для аутентификации.
Логи
fly logs # Логи в реальном времени
fly logs --no-tail # Последние логи
SSH-консоль
fly ssh console
Устранение неполадок
"App is not listening on expected address"
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 -y
Примечание: 512MB слишком мало. 1GB может работать, но может привести к OOM под нагрузкой или с подробным логированием. Рекомендуется 2GB.
Проблемы с блокировкой Gateway
Gateway отказывается запускаться с ошибками "already running".
Это происходит, когда контейнер перезапускается, но файл блокировки PID сохраняется на томе.
Решение: Удалите файл блокировки:
fly ssh console --command "rm -f /data/gateway.*.lock"
fly machine restart <machine-id>
Файл блокировки находится в /data/gateway.*.lock (не в поддиректории).
Конфигурация не читается
Если используется --allow-unconfigured, gateway создает минимальную конфигурацию. Ваша пользовательская конфигурация в /data/openclaw.json должна читаться при перезапуске.
Проверьте, что конфигурация существует:
fly ssh console --command "cat /data/openclaw.json"
Запись конфигурации через SSH
Команда fly ssh console -C не поддерживает перенаправление shell. Для записи файла конфигурации:
# Используйте echo + tee (pipe с локального на удаленный)
echo '{"your":"config"}' | fly ssh console -C "tee /data/openclaw.json"
# Или используйте sftp
fly sftp shell
> put /local/path/config.json /data/openclaw.json
Примечание: fly sftp может не сработать, если файл уже существует. Сначала удалите:
fly ssh console --command "rm /data/openclaw.json"
Состояние не сохраняется
Если вы теряете учетные данные или сессии после перезапуска, директория состояния записывается в файловую систему контейнера.
Решение: Убедитесь, что OPENCLAW_STATE_DIR=/data установлен в fly.toml и переразверните.
Обновления
# Получить последние изменения
git pull
# Переразвернуть
fly deploy
# Проверить здоровье
fly status
fly logs
Обновление команды машины
Если вам нужно изменить команду запуска без полного передеплоя:
# Получить ID машины
fly machines list
# Обновить команду
fly 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 и т.д.).
Для защищенного развертывания без публичного доступа используйте приватный шаблон.
Когда использовать приватное развертывание
- Вы делаете только исходящие вызовы/сообщения (без входящих webhook)
- Вы используете ngrok или Tailscale туннели для любых webhook-колбэков
- Вы получаете доступ к gateway через SSH, прокси или WireGuard вместо браузера
- Вы хотите, чтобы развертывание было скрыто от интернет-сканеров
Настройка
Используйте fly.private.toml вместо стандартной конфигурации:
# Развернуть с приватной конфигурацией
fly deploy -c fly.private.toml
Или преобразовать существующее развертывание:
# Перечислить текущие IP
fly ips list -a my-openclaw
# Освободить публичные IP
fly ips release <public-ipv4> -a my-openclaw
fly ips release <public-ipv6> -a my-openclaw
# Переключиться на приватную конфигурацию, чтобы будущие развертывания не выделяли публичные IP
# (удалить [http_service] или развернуть с приватным шаблоном)
fly deploy -c fly.private.toml
# Выделить только приватный IPv6
fly ips allocate-v6 --private -a my-openclaw
После этого fly ips list должен показывать только IP типа private:
VERSION IP TYPE REGION
v6 fdaa:x:x:x:x::x private global
Доступ к приватному развертыванию
Так как нет публичного URL, используйте один из этих методов:
Вариант 1: Локальный прокси (проще всего)
# Перенаправить локальный порт 3000 в приложение
fly proxy 3000:3000 -a my-openclaw
# Затем откройте http://localhost:3000 в браузере
Вариант 2: VPN WireGuard
# Создать конфигурацию WireGuard (один раз)
fly wireguard create
# Импортировать в клиент WireGuard, затем получить доступ через внутренний IPv6
# Пример: http://[fdaa:x:x:x:x::x]:3000
Вариант 3: Только SSH
fly ssh console -a my-openclaw
Webhook с приватным развертыванием
Если вам нужны webhook-колбэки (Twilio, Telnyx и т.д.) без публичного доступа:
- ngrok туннель - Запустите ngrok внутри контейнера или как sidecar
- Tailscale Funnel - Предоставьте определенные пути через Tailscale
- Только исходящие - Некоторые провайдеры (Twilio) прекрасно работают для исходящих звонков без webhook
Пример конфигурации voice-call с ngrok:
{
"plugins": {
"entries": {
"voice-call": {
"enabled": true,
"config": {
"provider": "twilio",
"tunnel": { "provider": "ngrok" }
}
}
}
}
}
Туннель ngrok запускается внутри контейнера и предоставляет публичный webhook URL без раскрытия самого приложения Fly.
Преимущества безопасности
| Аспект | Публичный | Приватный |
|---|---|---|
| Интернет-сканеры | Обнаруживается | Скрыт |
| Прямые атаки | Возможны | Заблокированы |
| Доступ к Control UI | Браузер | Прокси/VPN |
| Доставка webhook | Прямая | Через туннель |
Примечания
- Fly.io использует x86 архитектуру (не ARM)
- Dockerfile совместим с обеими архитектурами
- Для онбординга WhatsApp/Telegram используйте fly ssh console
- Постоянные данные хранятся на томе в /data
- Signal требует Java + signal-cli; используйте пользовательский образ и оставьте память на уровне 2GB+.
Стоимость
С рекомендуемой конфигурацией (shared-cpu-2x, 2GB RAM):
- ~$10-15/месяц в зависимости от использования
- Бесплатный тариф включает некоторую квоту
См. тарифы Fly.io для деталей.