SSD Nodes Learn Hosting plans →
Руководства Matt ConnorАвтор: Matt Connor · Обновлено 2026-08-28

Как запустить OpenBot AI-сотрудников на своем VPS

Разверните OpenBot в изолированных контейнерах с собственными браузерами Chromium. Узнайте, как шлюз контролирует действия агентов и сколько оперативной памяти требует каждый бот.

Что вы получаете при самостоятельном хостинге OpenBot AI-сотрудников

Вы размещаете OpenBot AI-сотрудников самостоятельно, запуская один сервер-шлюз и по одному контейнеру на каждого бота на оборудовании, которое вы контролируете. Каждый контейнер бота содержит собственный браузер Chromium и отдельный том для рабочей области с профилем браузера, который сохраняется между сессиями. Каждое действие, которое бот выполняет на компьютере, с файлом, MCP (model context protocol) сервером или компонентом интерфейса, проходит через этот шлюз. Шлюз проверяет действие на соответствие политике перед выполнением и регистрирует его после. Если цикл агента, который оборачивает этот шлюз, для вас пока в новинку, пошаговое руководство в изучении AI-агентов с нуля поможет вам написать небольшой цикл самостоятельно, прежде чем вы доверите боту браузер и свои учетные данные.

OpenBot публикуется компанией CopilotKit под лицензией MIT на github.com/CopilotKit/openbot. Первый релиз с тегом v0.0.1 был опубликован 17 августа 2026 года, и проект позиционирует себя как альфа-версия в стадии активной разработки. Относитесь к нему как к серьезной архитектуре с возможными недоработками ранней стадии.

Интересная часть этой архитектуры является одновременно и самой затратной. Браузер для каждого агента — это расход оперативной памяти, который многие забывают учесть при планировании, поэтому перед установкой необходимо рассчитать требования к ресурсам.

Как шлюз определяет каждое действие

API-сервер на порту 3001 является единственным путем к компьютеру бота. Перед выполнением действия в браузере шлюз определяет цель на основе снимка страницы, оценивает правила политики CEL (common expression language) в контексте, записывает строку аудита с принятым решением и только после этого вызывает контейнер. Если после этого выполнение завершается неудачей, записывается вторая строка. Документация четко определяет границу: компьютер не принимает решений по политике, границей действия является серверный шлюз. Это разделение имеет название за пределами OpenBot, поскольку цикл, определения инструментов, проверки разрешений и состояние сессии вместе образуют обвязку вокруг модели, а данный шлюз является её частью, отвечающей за разрешения.

Политика работает по принципу «запрещено по умолчанию», при этом правила запрета оцениваются перед правилами разрешения. Направление сбоя важнее синтаксиса правил. Отсутствующая политика не разрешает ничего, а некорректное правило приводит к блокировке независимо от того, является ли оно запрещающим или разрешающим. Таким образом, ошибка в политике приведет к остановке бота, а не к его бесконтрольной работе с вашими учетными записями. Этот уровень управляет тем, что бот делает, а не тем, что он читает. Поэтому страница с инструкциями для агента остается отдельной проблемой — это та же поверхность для prompt injection, с которой вы сталкиваетесь, когда передаете агенту результаты из собственного экземпляра SearXNG.

Журнал аудита хранится в PostgreSQL, поэтому он сохраняется после перезагрузки. Передача управления записывается как computer.help_requested, computer.control_taken и computer.control_released — именно так вы видите, как бот запрашивает участие человека, и как человек возвращает управление. Секреты записываются как количество символов, а не как значения. Операции с файлами фиксируют путь и размер, но не содержимое. Если вам нужна та же граница контроля без использования браузера, ограничение действий AI-агента через подтверждения описывает этот более узкий сценарий.

Сколько оперативной памяти и дискового пространства потребляет один бот

Проект публикует измеренные показатели для одного бота на архитектуре arm64. Это единственные цифры по планированию ресурсов, которые предоставляет OpenBot. Они описывают работу одного бота на одной архитектуре, поэтому рассматривайте их как отправную точку, а не как готовый план масштабирования.

ChartOpenBot published resource figures, one Bot on arm64 (August 2026)
The data behind this chart
[
  {
    "label": "Measured, one Bot",
    "memory_gb": 0.55,
    "disk_gb": 5.3,
    "vcpu": 0.06
  },
  {
    "label": "Documented minimum",
    "memory_gb": 2,
    "disk_gb": 8,
    "vcpu": 1
  },
  {
    "label": "Documented recommended",
    "memory_gb": 4,
    "disk_gb": 10,
    "vcpu": 2
  }
]

Пиковое потребление памяти составило 0.55 ГБ для одного бота, при этом задокументированный минимум составляет 2 ГБ, а рекомендуемый объем — 4 ГБ. Разница между измеренным значением и минимумом — это запас для Chromium при нагрузке, так как потребление памяти браузером зависит от открытых страниц, а не от процесса в состоянии покоя. Потребление CPU в простое близко к нулю и составляет 0.06 ядра в верхней границе измеренного диапазона, поэтому CPU — это не тот ресурс, который станет основным ограничением. Основной ресурс — диск. Только сам образ занимает 5.3 ГБ при рекомендуемом объеме диска в 10 ГБ. Такой размер обусловлен тем, что вместе с Chromium в образ включены бинарные файлы Playwright для Firefox и WebKit.

Эти данные не показывают стоимость запуска нескольких ботов одновременно, и проект не публикует таких цифр. Задокументированный минимум — это значение, которое проект готов официально указывать, а не результат наблюдения под реальной нагрузкой. Именно поэтому при выборе между PhotoPrism и Immich стоит ориентироваться на их фактическое потребление RAM, а не на заявленные системные требования. Проводите измерения самостоятельно. Запустите одного бота, дайте ему реальную задачу с открытой страницей и наблюдайте за контейнером во время работы.

docker stats --no-stream
free -m

Используйте значение из столбца MEM USAGE для контейнера бота в качестве базовой величины, добавьте к нему потребление шлюза и PostgreSQL, а затем умножьте полученную сумму на количество ботов, которые будут работать одновременно. Даже простаивающий бот удерживает процесс браузера, поэтому множитель применяется ко всем существующим ботам, а не только к активным. Расчет выполняется так же, как при планировании RAM и CPU для VPS с агентом для программирования, а работа с браузером описана в разделе запуск headless-браузера для агентов на VPS.

Одна особенность Chromium влияет на небольшие конфигурации. OpenBot запускает Chromium с флагом --disable-dev-shm-usage, поэтому браузер записывает данные в /tmp вместо /dev/shm. Это позволяет избежать сбоев на хостах с малым объемом /dev/shm и переносит нагрузку на корневую файловую систему. Это еще одна причина, по которой рекомендуемый объем диска больше размера самого образа.

Как разместить OpenBot на собственном VPS?

Вам потребуются Docker, Bun 1.3 или новее, проект CopilotKit Intelligence и API-ключ для модели. Документация по разработке также предполагает наличие lsof, python3 и curl на сервере. Клонируйте помеченный релиз, а не main, так как main в альфа-проектах меняется без предупреждения.

git clone --branch v0.0.1 https://github.com/CopilotKit/openbot.git
cd openbot
cp .env.example .env

Подготовьте проект Intelligence. Эти три команды записывают ключ среды выполнения и токен лицензии в ваш файл окружения.

npx --yes copilotkit@latest login
npx --yes copilotkit@latest project select
npx --yes copilotkit@latest license --write

Сгенерируйте ключ, который шифрует сохраненные учетные данные, и поместите результат в .env как KEY_ENCRYPTION_KEY. Добавьте ваш OPENAI_API_KEY в тот же файл или установите BOT_PROVIDER в значение anthropic или google с соответствующим ключом.

openssl rand -base64 32

Затем выполните установку и запуск.

bun install
bash scripts/start.sh

scripts/start.sh запускает Docker-сервисы, выполняет миграции базы данных, запускает сервер и приложение, а также проверяет их работоспособность. По завершении приложение будет отвечать на порту 3010, а API — на порту 3001. Скрипт сообщает о конфликтах портов и не затрагивает уже запущенные сервисы, поэтому повторный запуск безопасен.

Проверьте работу с самого сервера, прежде чем открывать доступ извне.

curl -sS -o /dev/null -w '%{http_code}\n' http://127.0.0.1:3010
ss -ltnp | grep -E ':(3010|3001|4100|4500|5432)'

200 в результате первой команды означает, что приложение работает. Вторая команда показывает, к каким адресам привязаны эти порты, и это самый важный ответ при работе на VPS. Строка 127.0.0.1:3001 означает, что сервис доступен только локально на сервере. Строка 0.0.0.0:3001 означает, что сервис доступен любому, кто может направить трафик на ваш сервер.

Единый образ контейнера

В документации по развертыванию также поставляется единый образ, содержащий приложение, API и Chromium, который работает на порту 3001.

docker build -t openbot .
docker run -p 127.0.0.1:3001:3001 --env-file .env \
  -e EMBEDDED_POSTGRES=on -v openbot-data:/var/lib/postgresql/data openbot

EMBEDDED_POSTGRES=on запускает PostgreSQL внутри контейнера и применяет миграции при старте. Именованный том сохраняет историю аудита при переразвертывании; без него каждая пересборка приводит к потере этой истории. Если вы указываете DATABASE_URL на управляемую базу данных, на ней должно быть включено расширение vector. Управляемые сервисы, такие как RDS, Cloud SQL и Azure Database, поддерживают это расширение, но ни один из них не включает его автоматически. Поэтому миграция на чистой управляемой базе данных завершится ошибкой, так как тип столбца vector еще не существует.

Выполняйте миграции как этап релиза, если база данных является внешней.

docker run --rm --env-file .env openbot \
  sh -c "cd /app/server && bun x drizzle-kit migrate --config=drizzle.config.ts"

Этот образ намеренно не публикует порт браузера. В нем также отсутствует супервизор, так как супервизору требуется Docker socket, который не предоставляется serverless-платформами. Без супервизора каждый бот использует один браузер и, следовательно, один набор учетных данных, что нарушает изоляцию, ради которой стоило запускать отдельные контейнеры для каждого бота. Если раздельные учетные данные для каждого бота — это то, зачем вы здесь, запускайте стек compose с установленными COMPUTER_SUPERVISOR_URL и SUPERVISOR_TOKEN на хосте, где вы принимаете соответствующие риски. Процесс, имеющий доступ к Docker socket, может запустить привилегированный контейнер, поэтому на практике он обладает правами root на хосте. Это веская причина держать OpenBot на отдельной машине, в том же духе, что и предоставление агентам для программирования одноразовой виртуальной машины.

Почему OPENBOT_SINGLE_USER — это настройка для ноутбука

.env.example поставляется с OPENBOT_SINGLE_USER=true. Эта настройка принимает любой запрос как запрос от одного администратора и полностью пропускает вход в систему. На ноутбуке это удобно, так как единственный клиент, который может получить доступ к порту, — это вы. На VPS это означает, что первый человек, который обратится к порту 3010, станет администратором системы, хранящей зашифрованные учетные данные и управляющей браузером, в котором вы уже авторизованы в своих аккаунтах.

Существует два корректных способа запуска. Оставьте OPENBOT_SINGLE_USER=true, привяжите все порты к 127.0.0.1 и обращайтесь к приложению только через SSH-туннель или частный сетевой интерфейс.

ssh -N -L 3010:127.0.0.1:3010 -L 3001:127.0.0.1:3001 you@your-vps

В этом случае приложение будет доступно по адресу http://localhost:3010 в вашем собственном браузере, что считается безопасным контекстом. Благодаря этому файлы cookie для входа и функции браузера, необходимые для работы «живого» экрана, будут функционировать корректно. Другой способ — отключить однопользовательский режим и настроить реального провайдера идентификации. Поддерживаются Google, Microsoft Entra, Okta, SAML и OIDC. Для любого провайдера также требуется BETTER_AUTH_SECRET длиной 32 символа или более, BETTER_AUTH_URL, установленный в базовый URL публичного API для обратных вызовов OAuth, INITIAL_ADMIN_EMAILS и TRUSTED_ORIGINS. Учетные данные провайдера должны быть полными, так как неполная конфигурация провайдера останавливает запуск вместо перехода к открытому доступу. Если причина, по которой вы добавляете учетные записи, заключается в том, что каждый член команды хочет иметь собственного агента, а не собственный браузер, то OneCLI изначально спроектирован именно для такого сценария: один изолированный агент на человека, а ключи модели хранятся в едином шлюзе.

Если приложение доступно по публичному имени, настройте перед ним TLS (transport layer security). Страница, передаваемая через обычный http:// на любом хосте, кроме localhost, не является безопасным контекстом. В результате файлы cookie с пометкой Secure не сохраняются, и вход в систему завершается ошибкой, которая выглядит как баг в OpenBot.

Ограничение доступа к низкоуровневым портам

В документации по безопасности OpenBot указано, что низкоуровневые конечные точки сервисов защищены токенами, должны оставаться приватными и не должны использоваться для обхода шлюза. Токены — это второй уровень защиты. Первый уровень заключается в том, что порт вообще не должен быть доступен извне.

Компьютер агента ожидает подключений на порту 4100 и требует COMPUTER_TOKEN. Конечные точки бота работают на портах 4200 и 4201. Супервизор ожидает подключений на порту 4500 на хосте и 4300 внутри своего контейнера. PostgreSQL работает на порту 5432. Ни один из этих портов не должен быть доступен через публичный интерфейс; в однопользовательской конфигурации это также относится к приложению и API.

sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp
sudo ufw enable
sudo ufw status verbose

Существует ловушка, в которую попадают те, кто считает, что одного лишь межсетевого экрана достаточно. Публикация порта контейнера с помощью -p 3001:3001 заставляет Docker добавить правило DNAT. В результате трафик обрабатывается в цепочке FORWARD и никогда не проходит через цепочку INPUT, которая управляется политикой «запретить по умолчанию» в ufw. Порт остаётся открытым, даже если ufw status по-прежнему выводит Status: active. Привязывайте опубликованный порт к интерфейсу обратной связи (loopback) непосредственно в параметрах маппинга, как -p 127.0.0.1:3001:3001, или укажите адрес хоста в файле compose. Проверяйте результат с помощью ss -ltnp, а не ufw status. Эта ловушка не является специфичной для OpenBot, поэтому выполняйте аналогичную проверку для всех остальных контейнеров, опубликованных на сервере, включая те, что обслуживают медиатеку Jellyfin, стилизованную под видеопрокат 90-х.

OpenBot не является автономным стеком

Учитывайте это перед планированием развертывания. OpenBot зависит от проекта CopilotKit Intelligence, который хранит постоянные потоки и историю диалогов вне вашего сервера. При запуске сервер проверяет INTELLIGENCE_API_URL, INTELLIGENCE_GATEWAY_WS_URL, INTELLIGENCE_API_KEY и COPILOTKIT_LICENSE_TOKEN; все четыре параметра должны присутствовать одновременно, иначе запуск завершится ошибкой. По состоянию на август 2026 года доступен бесплатный тарифный план, кроме того, Intelligence можно развернуть самостоятельно, поэтому полностью локальное развертывание возможно, хотя оно требует больше усилий, чем описано в руководстве по быстрому старту.

Модель является второй внешней зависимостью. В комплекте поставки ничего нет. BOT_PROVIDER поддерживает openai, anthropic или google, а OPENAI_BASE_URL указывает путь OpenAI на любой совместимый endpoint. Сюда относится запуск Ollama на VPS для самостоятельного хостинга LLM, если вы хотите, чтобы токены оставались на вашем оборудовании. Управление браузером предъявляет высокие требования к модели, поэтому протестируйте локальную модель на реальной задаче, прежде чем переходить на неё окончательно.

Запуск в одном экземпляре

Шлюз кэширует снимки страниц в оперативной памяти серверного процесса. При наличии двух реплик снимок, сделанный одним процессом, будет недоступен другому. Это приводит к периодическим сбоям с ошибками вида element-not-found, которые выглядят случайными. Документация по развертыванию содержит четкое требование: запускайте только один экземпляр и ограничьте максимальное количество инстансов в вашей платформе значением 1. Это ограничение будет снято, когда кэширование снимков перенесут в базу данных. До тех пор масштабируйте OpenBot путем увеличения ресурсов сервера, а не добавления новых узлов. Изоляция между ботами по-прежнему обеспечивается контейнерами для каждого отдельного бота, точно так же, как песочницы self-hosted агентов предотвращают влияние ошибок одного агента на работу остальных.

Типичные сбои и их признаки

Процесс завершается сразу после заполнения .env. Сервер проверяет конфигурацию перед запуском. Неполный блок Intelligence, отсутствие KEY_ENCRYPTION_KEY или провайдер OAuth с указанным client ID, но без secret, приводят к остановке запуска, а не к работе в ограниченном режиме. Прочитайте первое сообщение об ошибке, исправьте указанное поле и запустите процесс снова.

Миграции завершаются с ошибкой при использовании управляемой базы данных. Расширение vector не включено по умолчанию, поэтому миграция пытается создать тип столбца, который PostgreSQL не поддерживает. Подключитесь как суперпользователь, выполните CREATE EXTENSION vector;, а затем повторите шаг миграции.

Приложение загружается, но сессия входа не сохраняется. Вы используете обычный http:// на публичном адресе, что не является безопасным контекстом, поэтому файл cookie Secure отбрасывается. Настройте TLS перед приложением или используйте SSH-туннель, чтобы браузер работал через localhost.

Боты используют общие учетные данные, хотя должны быть разделены. Супервизор не запущен, поэтому для каждого бота нет отдельного окружения, и все они используют общий браузер. Убедитесь, что параметр COMPUTER_SUPERVISOR_URL задан и супервизор имеет доступ к Docker socket.

Бот останавливается и запрашивает помощь. Это штатное поведение системы. В журнале аудита фиксируется computer.help_requested, вы берете управление на себя в режиме реального времени, и факт передачи управления записывается с обеих сторон.

FAQ

Безопасно ли оставлять OPENBOT_SINGLE_USER включенным при развертывании на VPS?

Только в том случае, если шлюз недоступен из Интернета. OPENBOT_SINGLE_USER=true принимает любой запрос как запрос от администратора без авторизации, поэтому любой, кто может открыть порт, получает полный контроль над развертыванием, сохраненными учетными данными и сессией браузера. Это допустимо, если все порты привязаны к 127.0.0.1, а доступ к приложению осуществляется через SSH-туннель или частный сетевой интерфейс. При работе через публичный интерфейс отключите эту опцию и настройте Google, Microsoft Entra, Okta или OIDC вместе с BETTER_AUTH_SECRET, BETTER_AUTH_URL, INITIAL_ADMIN_EMAILS и TRUSTED_ORIGINS.

Сколько оперативной памяти нужно одному боту OpenBot?

Согласно опубликованным данным проекта для одного бота на архитектуре arm64, пиковое потребление памяти составляет 0.55 ГБ, при этом 2 ГБ является задокументированным минимумом, а 4 ГБ — рекомендуемым значением. Официальных данных для нескольких ботов одновременно нет, так как каждый из них запускает отдельный экземпляр Chromium. Запустите одного бота для выполнения реальной задачи, проверьте потребление памяти контейнером в docker stats, добавьте потребление шлюза и базы данных, а затем умножьте на количество ботов, которые должны работать одновременно.

Нужна ли учетная запись CopilotKit для самостоятельного хостинга OpenBot?

Да. OpenBot зависит от проекта CopilotKit Intelligence для обеспечения работы потоков и памяти, и сервер отказывается запускаться, если не заданы URL-адрес Intelligence API, URL-адрес WebSocket шлюза, API-ключ и лицензионный токен. По состоянию на август 2026 года доступен бесплатный тарифный план, а Intelligence можно развернуть самостоятельно, поэтому зависимость от облачного сервиса можно устранить при дополнительных усилиях. Вы также должны предоставить собственный API-ключ для модели, так как ни одна модель не поставляется вместе с OpenBot.

Почему каждый бот использует свой браузер, а не общий?

Потому что профиль браузера — это идентификатор. Общий браузер означает общие файлы cookie и общие сессии, поэтому один бот, вошедший в учетную запись, делает всех ботов авторизованными в этой же учетной записи. Использование отдельных контейнеров для каждого бота дает каждому «сотруднику» свой профиль и свои логины. Платой за это является расход оперативной памяти, так как Chromium для каждого бота — это самый ресурсоемкий компонент при расчете нагрузки.

Какие порты OpenBot должны быть открыты в брандмауэре?

Никакие из низкоуровневых портов. Агент на 4100, конечные точки бота на 4200 и 4201, супервизор на 4500 и PostgreSQL на 5432 должны оставаться приватными. Проект защищает их токенами и требует, чтобы они в любом случае оставались недоступными извне. Публикуйте только то, к чему человеку нужен прямой доступ, и помните, что порт контейнера, опубликованный с помощью -p 3001:3001, доступен независимо от правила ufw default-deny, так как правило DNAT в Docker направляет этот трафик по пути FORWARD, минуя INPUT.