opencode-web на VPS: AI-ассистент в кармане

· 12 мин чтения

Я пользуюсь AI-ассистентами каждый день — для кода, архитектурных решений, поиска информации. Но есть проблема: все инструменты привязаны к терминалу или IDE. Если я вышел из-за ноутбука — AI остался там же. В кафе, в дороге, с телефона — доступа нет.

Можно взять SaaS-подписку: Claude Code в облаке, Codex через мобильное приложение. Но тогда мой код, мои MCP-серверы и конфигурация остаются на чужой инфраструктуре. А свой API-ключ — тем более.

Решение: поднять opencode-web на своём VPS. Один сервер, три интерфейса: Web UI для телефона, TUI для ноутбука, REST API для автоматизации. Свой ключ, свои настройки, полный контроль.

В этой статье — мой личный опыт: как я выбрал VPS, настроил безопасность, прикрутил аутентификацию через Yandex ID и что из этого получилось.

У кого из AI-агентов есть web-доступ

Прежде чем поднимать свой сервер, стоит понять — а есть ли вообще альтернативы? Я сравнил популярных AI-агентов по наличию удалённого доступа через браузер или телефон.

АгентWeb-доступКак работаетЧто под капотом
Claude Code✅ Remote Controlclaude remote-control → QR-код → claude.ai/code или мобильное приложение ClaudeЛокальная CLI-сессия регистрируется на серверах Anthropic. Браузер/телефон — окно в эту сессию. Порты не открываются.
Codex CLI⚠️ Через мобильное приложение + сторонние web UIChatGPT mobile app подключается к Codex App на macOS/Windows. Либо npx rmtcdx / remcodex — сторонние web-интерфейсыОфициально: remote control через аккаунт OpenAI. Неофициально: rmtcdx с поддержкой Tailscale, codex-remote-hub на ttyd+tmux
OpenCode✅ Нативный opencode webОдна команда — и поднят HTTP-сервер с Web UI и REST API. Любой браузер, любой телефон.Всё на вашем сервере. Никакой привязки к облаку вендора. Basic auth или OAuth-прокси.
AiderНетТерминал, только локально
ClineНетVS Code extension, только локально
CursorНетФорк VS Code, только локально

Главное отличие opencode-web: он не «показывает» локальную сессию через чужой сервер, как Remote Control у Claude Code. Он сам является сервером. Вы решаете, на каком железе он работает, какую модель использует и кто имеет доступ.

Ещё один важный нюанс: opencode-web поднимает не только Web UI, но и REST API — тот же самый, с которым работает opencode attach и opencode run. Один бэкенд обслуживает и браузер, и терминал, и автоматизацию.

У Claude Code и Codex тоже есть API, но оно либо завязано на облако, либо требует отдельных решений. У OpenCode — из коробки.

Источники:

Какие бывают VPS и сколько это стоит

Для opencode-web не нужно мощное железо. Минимальные требования — 1 vCPU и 1 GB RAM. Комфортно — 2 vCPU и 2 GB. Я собрал актуальные варианты на рынке:

ПровайдерКонфигурацияЦенаПримечание
Oracle Cloud Free4 ARM / 24 GB€0Регистрация сложная, может убить idle-машину
Hetzner CX222 x86 / 4 GB€3.79/месЛучшая цена/качество в Европе, x86
Netcup VPS 1000 G112 x86 / 4 GB€3.99/мес128 GB SSD — в 3 раза больше диска
RackNerd (sale)1 vCPU / 1 GB~$1/месМинимум, US only
Yandex Cloud2 vCPU / 2 GB~€17/месДороже в 3–5 раз, но российский IP

Я остановился на Yandex Cloud. Конфигурация: 2 vCPU, 8 GB RAM, 40 GB диск — 4 800 ₽/мес. Это с большим запасом: средняя утилизация CPU — 20%, память тоже не упирается в потолок. Можно взять минимальную конфигурацию (2 vCPU / 2 GB) — будет сильно дешевле. Я взял с запасом, потому что сервер используется и для других задач.

Важный момент: код хранится в git-репозитории. На сервере — только рабочая копия (working copy), которую opencode клонирует и редактирует. Поэтому объём диска не критичен, хватит 20 GB.

Безопасность: чтобы не было мучительно больно

Зачем вообще защищать сервер

opencode-web — это не статический сайт и не блог. Это агент с правами на файловую систему, сеть и выполнение команд. Если кто-то получит к нему доступ, он сможет:

Плюс объективная реальность: любой публичный IP сканируется ботами в течение минут после создания. Брутфорс SSH, сканирование открытых портов, поиск уязвимых сервисов — это фоновый шум интернета, не направленная атака. Защита нужна не от хакера-профи, который целенаправленно охотится за вами, а от автоматизированных сканеров, которые стучатся во все двери подряд.

Обычный веб-сервис — умеренный риск. AI-агент с правами на файловую систему и API-ключами — высокий риск. Поэтому защита тут в три слоя, а не один пароль.

Три слоя защиты

СлойЧто защищаетИнструмент
СетьДоступ к порту 4096 из интернетаTailscale + ufw
ПриложениеДоступ к Web UIOAuth через Yandex ID
ОСДоступ по SSHКлючи вместо паролей, fail2ban, автообновления

Идея простая: даже если один слой пробит, следующие сдерживают атаку. Атакующий должен пройти через Tailscale (не зная ваших устройств), затем через OAuth (не имея вашего Яндекс-аккаунта), и только потом попадает к opencode-web.

Цепочка защиты сверху вниз:

1. Интернет
2. Tailscale — только ваши устройства
3. ufw — только трафик с tailscale0
4. OAuth — только вы (Yandex ID)
5. opencode-web :4096
6. SSH — ключи + fail2ban

Tailscale: приватная сеть вместо открытых портов

Первое правило: не открывайте порты наружу. Никаких 0.0.0.0:4096 в интернет. Вместо этого — Tailscale.

Tailscale — это mesh-VPN на базе WireGuard. Бесплатно до 100 устройств. Вы ставите клиент на VPS и на телефон — и они оказываются в одной приватной сети. После этого opencode-web слушает 0.0.0.0, но файрвол (ufw) пропускает трафик только с интерфейса tailscale0:

Terminal window
ufw allow in on tailscale0
ufw --force enable

Теперь сервер виден только вашим устройствам в Tailscale-сети. Телефон, ноутбук, планшет — подключаются по внутреннему IP вида 100.x.x.x:4096.

Настройка Tailscale на сервере — одна команда:

Terminal window
curl -fsSL https://tailscale.com/install.sh | sh
tailscale up

После этого открываете ссылку в браузере, авторизуетесь — и сервер в сети. На телефоне устанавливаете приложение Tailscale (App Store / Play Market) и логинитесь тем же аккаунтом.

Аутентификация через Yandex ID

Сам OpenCode Web поддерживает HTTP basic auth. Но для личного сервера хочется нормальную аутентификацию — без запоминания ещё одного пароля и с двухфакторкой из коробки.

Важно: если вы используете Tailscale и доверяете всем устройствам в своей сети — аутентификация не обязательна. Приватная сеть сама по себе уже отсекает внешний мир. Но я решил добавить OAuth как дополнительный слой.

Схема получилась такой:

Браузер
↓ Tailscale
Caddy :443 (reverse proxy, HTTPS)
auth-proxy (JS, 165 строк)
↓ проверка токена
├─ Yandex ID OAuth
└─ opencode-web :4096

Caddy работает как reverse proxy с автоматическим HTTPS (Let’s Encrypt). Я привязал к серверу домен второго уровня — это даёт нормальный сертификат и человекочитаемый URL вместо http://100.x.x.x:4096.

Auth proxy — это тонкая прослойка на JavaScript, 165 строк кода. Я попросил OpenCode написать её. Она делает ровно одну вещь: проверяет OAuth-токен Yandex ID перед тем, как пропустить запрос к opencode-web. Никакой логики, кроме аутентификации.

Алгоритм:

  1. Регистрируете OAuth-приложение в Яндекс ID — получаете client_id и client_secret
  2. Callback URL ведёт на ваш сервер — после входа Яндекс редиректит обратно с токеном
  3. Auth proxy проверяет токен через API Яндекса и либо пускает к opencode-web, либо возвращает 401

Почему Yandex ID:

Повторюсь: без OAuth можно обойтись. Tailscale уже даёт достаточную изоляцию. Но если хочется красивый URL с доменом и нормальный HTTPS — Caddy + auth proxy решают эту задачу.

SSH-харденинг и fail2ban

Несколько обязательных настроек на самом VPS:

Terminal window
# Только ключи, без паролей, без root-логина
sed -i 's/^#*PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config
sed -i 's/^#*PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config
sed -i 's/^#*PubkeyAuthentication.*/PubkeyAuthentication yes/' /etc/ssh/sshd_config
systemctl restart sshd

Плюс fail2ban для защиты от брутфорса SSH:

Terminal window
apt install -y fail2ban
systemctl enable --now fail2ban

И автоматические security-обновления, чтобы не пропустить критические патчи:

Terminal window
apt install -y unattended-upgrades

Основные концепции настройки

Я не буду публиковать полный setup-скрипт — он зависит от вашего провайдера и предпочтений. Вместо этого разберу ключевые шаги, чтобы вы понимали, что происходит.

Система: пользователь и зависимости

Первое правило — не запускайте opencode от root. Создайте отдельного пользователя:

Terminal window
adduser --gecos "" --disabled-password developer
usermod -aG sudo developer

Из пакетов понадобятся: curl, ufw, fail2ban, unattended-upgrades, jq. Всё ставится одной командой:

Terminal window
apt update && apt install -y curl ufw fail2ban unattended-upgrades jq

Установка OpenCode и конфигурация

OpenCode ставится официальным установщиком от имени созданного пользователя:

Terminal window
su - developer -c 'curl -fsSL https://opencode.ai/install.sh | sh'

После установки бинарник лежит в ~/.local/bin/opencode.

Минимальная конфигурация для web-сервера (~/.config/opencode/opencode.json):

{
"$schema": "https://opencode.ai/config.json",
"server": {
"port": 4096,
"hostname": "0.0.0.0"
}
}

Порт 4096 — стандартный для OpenCode. hostname: 0.0.0.0 — слушаем на всех интерфейсах, чтобы Tailscale-клиенты могли подключиться. Безопасность обеспечивает ufw, а не биндинг на localhost.

Провайдеры LLM (Anthropic, OpenAI, OpenRouter и др.) настраиваются через Web UI после первого входа — ключи хранятся локально на сервере.

systemd-сервис: чтобы переживало ребуты

OpenCode Web должен автоматически стартовать при загрузке и перезапускаться при падении. Для этого — systemd-юнит в пользовательском режиме (~/.config/systemd/user/opencode-web.service):

[Unit]
Description=OpenCode Web Server
After=network.target
[Service]
Type=simple
WorkingDirectory=%h
ExecStart=/home/developer/.local/bin/opencode web --port 4096 --hostname 0.0.0.0
Restart=on-failure
RestartSec=5
[Install]
WantedBy=default.target

Важный нюанс: пользовательский systemd требует lingering — иначе сервис умирает при выходе пользователя:

Terminal window
loginctl enable-linger developer

После этого запускаем:

Terminal window
su - developer -c "systemctl --user daemon-reload"
su - developer -c "systemctl --user enable --now opencode-web"

Проверяем, что сервер отвечает:

Terminal window
curl -s http://localhost:4096/global/health

Что получилось: Web UI, телефон и API

После настройки у меня работает один сервер, доступный тремя способами.

Web GUI с телефона

Открываю браузер на телефоне, ввожу Tailscale-адрес сервера (http://100.x.x.x:4096) — попадаю в полноценный интерфейс OpenCode. Можно начать новую сессию или продолжить существующую. Работает точно так же, как локальный TUI: те же агенты, те же MCP-серверы, те же права доступа к файловой системе.

Провайдер LLM и API-ключ настраиваются один раз через Web UI — и доступны с любого устройства в Tailscale-сети.

TUI с ноутбука

С ноутбука (тоже в Tailscale-сети) я подключаюсь через opencode attach:

Terminal window
opencode attach http://100.x.x.x:4096

Это даёт полноценный TUI-интерфейс, который работает с тем же бэкендом. Можно продолжить сессию, начатую с телефона, или наоборот — начать в терминале, а продолжить в браузере.

Зачем это нужно: TUI удобнее для интенсивной работы с кодом (клавиатура, быстрая навигация). Web UI — для быстрых вопросов с телефона. Сессии общие.

API из коробки

Неочевидный бонус: opencode web поднимает тот же REST API, что и opencode serve. Клиенты (TUI, Web UI) работают через него же. Это значит, что вы можете автоматизировать работу с агентом:

По сути, вы получаете AI-воркера, который живёт на вашем сервере и доступен через API в любой момент. Не нужно поднимать отдельный инстанс для каждой задачи — один сервер обслуживает все сценарии.

Вывод: стоит ли игра свеч

Я пользуюсь этой связкой уже несколько недель. Вот честный расклад.

Производительность: на конфигурации 2 vCPU / 8 GB RAM opencode-web работает с большим запасом. Средняя утилизация CPU — 20%, даже с учётом активной разработки и операций с git. Падений и тормозов не было.

Плюсы:

Минусы и ограничения:

Когда это имеет смысл:

Когда проще взять готовое:

Я для себя ответил однозначно: да, стоит. Возможность достать телефон и спросить агента о чём угодно — с моими ключами, моими MCP-серверами, моей конфигурацией — перевешивает затраты на сервер.