Как запустить OpenCode на сервере: автономные ИИ агенты

За последние три года слово «ИИ-агент» вы слышали точно. Может, даже работали с Claude Code или Codex — или хотя бы наблюдали со стороны. И вот беда: оба закрытые и проприетарные, заточены под модели своих авторов. Тут и появляется OpenCode — open-source harness-система, где агент читает файлы, гоняет тесты, дёргает другие модели в помощь, передаёт задачи субагентам, подключает MCP, скиллы, плагины. И никакой привязки к вендору: подключай официальных провайдеров, сторонние шлюзы, тот же GLM 5.3 или Claude Opus 5.5 — что хочешь.
Живёт агент полной жизнью, пока открыт терминал. Отошли на обед — сессия повисла где-то между «подумать» и «сделать». Закрыли ноутбук — всё умерло. А то и вовсе прервалась на самом интересном месте.
Выход — деплой OpenCode на сервер. О нём и поговорим.
Когда запускаешь opencode в терминале, кажется, что это просто удобная обёртка над LLM. На первый взгляд — да. Под капотом, правда, клиент-серверная схема: TUI общается с локальным HTTP-сервером, который публикует OpenAPI-спецификацию и отдаёт её любому клиенту. Архитектура изначально готова к тому, чтобы агент жил отдельно от того, кто на него смотрит.
opencode serve поднимает этот же сервер в headless-режиме: API, стрим событий и эндпоинт /doc со спецификацией, по которой генерируются SDK. Стучаться туда можно из CI или cron, из другого скрипта — или просто держать прогретым между запусками, чтобы не платить за холодный старт MCP и LSP каждый раз.
Но стоит обозначить весьма важный элемент — провайдер ИИ-моделей. Можно подключать ваши модели или другие провайдеры, а можно воспользоваться нашим сервисом BotHub, который предоставляет доступ к сотням новейших моделей, имеет OpenAI-совместимый шлюз и удобную оплату в рублях без VPN.
Дальше — чем serve отличается от run, что делать с прокси и правами и почему автономный агент без изоляции кончается плохо.
Хочу сделать оговорку, что в статье — только OpenCode. Настройка fail2ban, SSH, файрволла и прочей обвязки остаётся за кадром, эта не тема статьи нашей — сервер вы защищаете сами.
Как OpenCode устроен в серверном режиме
По умолчанию сервер слушает 127.0.0.1:4096, меняется флагами --hostname и --port. Для браузерных клиентов есть --cors, а --mdns позволяет машинам находить друг друга в локальной сети — полезно, когда их несколько, а прописывать адреса руками лень. И если у вас уже где-то запущен TUI, opencode serve спокойно поднимет второй сервер, не трогая первый.
Есть ещё флаг --server <url>, чтобы не плодить сущности, ибо opencode run будет стучаться в конкретный сервер вместо подъёма собственного.
И сразу один момент — пароль. Сервер торчит не только на localhost, так что настоятельно советую выставить OPENCODE_SERVER_PASSWORD, тогда включится HTTP basic auth, юзернейм по умолчанию opencode, меняется через OPENCODE_SERVER_USERNAME. Мелочь, а нервы сбережёт.
Зачем вообще серверный OpenCode?
А зачем вообще может пригодиться серверный OpenCode? Мы гоняем агентов на своей машине, деньги на токены и так тратим — зачем ещё и сервер оплачивать? Если коротко, то чтобы агент жил своей жизнью, а вы — своей.
CI/CD и PR-ревью
Ну самое простое - CI/CD и PR ревью. Конечно, вывод моделей недетерменированный, и не стоит заставлять агента оценивать код по шкале. Но для ревью весьма неплохо подойдет. OpenCode подключается к GitHub через приложение, вы можете упоминать в комментарии к пул-реквесту /opencode или /oc — и агент стартует прямо в GitHub Actions runner. Прочитает контекст, если захочет создаст ветку и откроет PR со своим фиксом. Иногда агенту можно даже доверить ревьюить пул-реквесты других агентов. Цирк, но работает.
Не хочется ставить приложение — пропишите шаг в workflow руками: npm install --global @opencode/cli, затем opencode run --standalone --model ... "промпт", ключ провайдера — через секрет репозитория. --standalone тут не украшательство: в CI нет запущенного TUI, и команда сама поднимет приватный сервер под задачу.
Ночные и cron-задачи
Допустим, вам жизненно необходим opencode run в systemd timer или cron. Есть готовый плагин opencode-scheduler: он использует нативный планировщик ОС — launchd на macOS, systemd на Linux, с фолбэком на cron. Скажем, ежедневный аудит зависимостей и отчёт по git log — повешено на расписание, забыто. В неинтерактивном режиме run не останавливается на вопросах, запрос разрешения отклоняется с обратной связью, и модель продолжает работу.
Удалённая команда и IDE
Этот вариант подойдет если один сервер обслуживает несколько клиентов сразу. IDE-плагины используют эндпоинт /tui, чтобы управлять интерфейсом через сервер — предзаполнить промпт или запустить его удалённо. Веб-интерфейс или Telegram-мост, хоть самописный дашборд — всё цепляется к одному процессу и видит одни и те же сессии. Если команда работает с агентами централизованно, такой деплой снимает изрядную часть возни.
Куда и как ставить?
Сценарии разобрали, но как же поставить на сервер opencode? И снова напомню, что SSH стоит настроить, ибо пока вы пишете свои конфиги, ваш порт может уже брутфорсить орава ботов.
По стандартной практике, тут два решения - либо вручную через установку и условный systemd-сервис, либо через Docker-контейнер.
systemd на VPS — минимум телодвижений
Вариант для чистого сервера, когда вы не боитесь, что агент что-то сломает в системе. OpenCode ставится глобально через npm i -g @opencode/cli — актуальная ветка v2 живёт под этим пакетом, а старый opencode-ai остался в линии 1.x.
Юнит-файл выглядит почти стандартно:
[Unit]
Description=OpenCode Server
After=network.target
[Service]
ExecStart=/usr/local/bin/opencode serve --port 4096 --hostname 0.0.0.0
Restart=on-failure
RestartSec=5
Environment=HOME=/root
[Install]
WantedBy=multi-user.target
Не забывайте про PATH. systemd-сервисы не наследуют PATH вашей оболочки, у них свой минимальный набор. Если OpenCode установлен через npm в ~/.npm-global/bin, сервис его просто не найдёт. И — что немаловажно — беда не только с самим бинарником, ведь всё, что агент вызывает через bash, по типу git, node, rg, make, тоже отсутствует в минимальном PATH, и команды падают с command not found.
Лечится явным Environment=PATH=..., а на NixOS — systemd.services.opencode-serve.path. HOME тоже задайте, дабы конфиги смог найти opencode.
Docker — изоляция и повторяемость
Не хочется думать про PATH, да и хоть какой-то изоляции хочется — значит следующий шаг Docker. Официальные образы живут в https://github.com/anomalyco/opencode/pkgs/container/opencode, теги версионированные, так что фиксируйте конкретную версию и не ловите сюрпризы при пересборке.
Запускается вот так:
docker run -p 4096:4096 \
-v /path/to/workspace:/workspace \
-e OPENCODE_SERVER_PASSWORD=your-password \
ghcr.io/anomalyco/opencode:2.0.0 serve --hostname 0.0.0.0
Docker даёт файловую систему, отделённую от хоста, и таким образом агент не сможет случайно переписать что-то в /etc или в вашем домашнем каталоге. Весьма ценно на недоверенном коде или в CI, где в репозитории может лежать что угодно. Только считайте это страховкой от случайностей, от случайного rm спасёт, от целенаправленного побега — увы. Ниже объясню, откуда это берётся.
Для CI/CD удобнее docker compose с pinned-образом. Workspace монтируйте отдельным volume, конфиги и сессии — ещё одним, чтобы не терять их между перезапусками. Ключ провайдера, как водится, через секрет репозитория.
Провайдер без привязки к вендору
OpenCode не требует ни Anthropic, ни OpenAI. Через пакет @ai-sdk/openai-compatible подключается любой совместимый эндпоинт — от локальной Ollama до облачного шлюза. Минимальный конфиг выглядит так:
{
"$schema": "https://opencode.ai/config.json",
"provider": {
"bothub": {
"npm": "@ai-sdk/openai-compatible",
"name": "Bothub Gateway",
"options": {
"baseURL": "https://openai.bothub.chat/v1"
},
"models": {
"gpt-6.1-sol": { "name": "GPT-6.1 Sol" },
"claude-sonnet-5.5": { "name": "Claude Sonnet 5.5" },
"glm-5.3": { "name": "GLM-5.3" }
}
}
},
"model": "bothub/gpt-6.1-sol"
}
Провайдер в примере — BotHub, эндпоинт https://openai.bothub.chat/v1, оплата российской картой, а по реферальной ссылке дают ещё 300 000 CAPS.
Кстати, названия моделей в конфиге — это ID для API; полный список лежит в каталоге провайдера. Хранить API-ключ прямо в конфиге — плохая идея, особенно на сервере. Конфиги имеют привычку уезжать в репозиторий вместе с ключом. Да и вы видели новости, что не день, то утечка env-файлов или MCP взломан. Безопаснее opencode auth login, тогда конфиг останется чистым.
Есть и поле small_model — отдельная модель под служебные задачи по типу заголовков сессий, компакций контекста. Сюда можно поставить что-нибудь подешевле, а то флагману в заголовках сессий делать нечего.
Проверка перед запуском сервера доступна по команде opencode run --model bothub/gpt-6.1-sol "ping". One-shot ответил — серверный режим тоже поднимется.
Агенты и субагенты
Инфраструктура готова, но нужно разобраться с тем, зачем мы вообще начали это мероприятие - агентная система.
Разрешения — первое, что стоит раздать, если агент должен работать без вас. Автономность с дефолтными настройками долго не живёт…
В OpenCode есть primary agent — тот, с кем вы или ваш клиент общаетесь напрямую, и subagent — исполнитель, которого primary зовёт под конкретную задачу. Субагенты запускаются в дочерних сессиях со своим контекстом, родитель видит только результат.
Каждое правило разрешения сводится к одному из трёх значений: allow — выполнить без вопросов, ask — запросить подтверждение, deny — заблокировать. Локально ask — норм. На сервере он вешает процесс, ибо opencode run неинтерактивен, а opencode serve может часами ждать ответа, которого не будет. Агент стоит, работа не делается.
Поэтому для серверных агентов лучше не использовать ask, либо точечные allow поверх deny по умолчанию, либо --auto, о нём ниже. Как настраивать агентов, я тут не разбираю — для этого есть моя прошлая статья про настройку воркфлоу, так что я тут краток.
Бывает, что закрывать bash целиком страшно, но и ask не вариант. На этот случай есть флаг --auto, который одобряет все запросы, кроме явно запрещённых. deny продолжает работать, ask превращается в allow. Компромисс понятный: запреты живут, но подтверждать каждый шаг не нужно.
И ещё нюансик — у субагентов есть собственный инструмент task, который определяет, каких субагентов может вызывать агент. Закрыли task через deny — субагент исчез из списка инструментов, и модель даже не пытается его дёрнуть.
Безопасность
Начну с неприятного, ведь OpenCode, о ужас, не песочница. В SECURITY.md это написано прямым текстом: «OpenCode does not sandbox the agent. The permission system exists as a UX feature… If you need true isolation, run OpenCode inside a Docker container or VM». В общем — справедливо, это только удобный UX, считать их обороной наивно.
Про пароль говорил, добавлю про сертификаты, коли сервер смотрит наружу, спрячьте его за nginx или Caddy с HTTPS. Basic auth поверх открытого HTTP держит разве что случайный скан-трафик.
MCP — то место, где я был бы осторожнее всего. В том же SECURITY.md сказано, что внешние MCP-серверы находятся «outside our trust boundary». В октябре 2026-го это подтвердилось на практике, вон недавно вредоносный MCP-сервер через OAuth-авторизацию выполнял код на Windows и WSL. CVE даже не запросили — MCP сочли вне модели угроз. Сканеры уязвимостей такие сборки не помечают, версию проверяйте руками. В общем, экосистема MCP сейчас напоминает ранние годы npm, когда все удобно, быстро, а насколько можно верить случайному публикатору — большой вопрос.
Отдельная песня — Bun, на котором работает OpenCode. Он читает HTTP_PROXY и HTTPS_PROXY как вздумается, где-то берёт, где-то игнорирует. socks5:// не переваривает вообще — подавай http://. И NO_PROXY с localhost и 127.0.0.1 поставьте обязательно, иначе агент может зациклиться на собственных запросах. Bun и socks5:// — отдельная боль, у меня прокси был socks, пришлось поднимать http-мост, но после я вообще отрубил переменные прокси.
Мониторинг
Серверный агент без наблюдаемости — плохой союзник: мало того что он втихую тратит деньги за токены, так ещё и упасть может. Как минимум health-check и логи. А счётчик токенов — тем более: кто знает, чем он там занимается ночью.
Health-check встроен, эндпоинт /global/health отдаёт { healthy: true, version: string }. Прицепите к внешнему монитору — uptime kuma подойдёт — и хотя бы будете знать, что процесс жив. Логи живут в journald или Docker logs, смотря как запущено. А еще достаточна полезна трассировка, для этого есть плагин opencode-otel, который экспортирует трейсы сессий через OpenTelemetry в Jaeger, Grafana Tempo, Datadog или Langfuse. В конфиг ставится одной строкой, дальше идут переменные окружения с эндпоинтами. После этого видно каждый шаг агента, от того какую модель он дёрнул, до того что он правил.
Для CI/CD удобно гонять opencode run --format json, где получается на выходе поток событий, который парсится и складывается в артефакты.
Заключение
Установка OpenCode на сервер — вечер. Дальше начинается настоящая работа девопс-инженера (или не совсем) - обезопасить, завернуть в контейнер, разобраться, почему Bun игнорирует ваш прокси, и настроить трассировку, пока агент не съел бюджет. Secure, Contain, Protect, общими словами. Если вы уже разворачивали селф-хостед приложения, всё это вам наверняка знакомо.
Автономный агент оправдан, когда он встроен в процесс, когда есть ночные аудиты, ревью пул-реквестов. Ставить агента ради самого агента — так себе план. И целые продакшен-деплои ему не доверяйте, пусть готовит PR, кнопку жмёте вы. Шутка, если что, ревьювить тоже надо.
Зато когда всё настроено, он работает, пока вы спите. И вы можете исполнить свою мечту — штамповать SaaS B2B AI стартапы каждую ночь! Лишь деньги на токены были бы.
KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.