opencode-web на VPS: AI-ассистент в кармане
Я пользуюсь 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 Control | claude remote-control → QR-код → claude.ai/code или мобильное приложение Claude | Локальная CLI-сессия регистрируется на серверах Anthropic. Браузер/телефон — окно в эту сессию. Порты не открываются. |
| Codex CLI | ⚠️ Через мобильное приложение + сторонние web UI | ChatGPT 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 — из коробки.
Источники:
- Claude Code Remote Control — официальная документация
- Claude Code on the web — сравнение режимов (web, Remote Control, терминал)
- Codex Remote Connections — официальная документация OpenAI
- rmtcdx — Codex Remote Web Client — сторонний web UI для Codex с поддержкой Tailscale
- claude-code-web — self-hosted web UI для Claude Code через SSH-туннель
- OpenCode CLI: attach — документация
opencode attachдля подключения к удалённому серверу
Какие бывают VPS и сколько это стоит
Для opencode-web не нужно мощное железо. Минимальные требования — 1 vCPU и 1 GB RAM. Комфортно — 2 vCPU и 2 GB. Я собрал актуальные варианты на рынке:
| Провайдер | Конфигурация | Цена | Примечание |
|---|---|---|---|
| Oracle Cloud Free | 4 ARM / 24 GB | €0 | Регистрация сложная, может убить idle-машину |
| Hetzner CX22 | 2 x86 / 4 GB | €3.79/мес | Лучшая цена/качество в Европе, x86 |
| Netcup VPS 1000 G11 | 2 x86 / 4 GB | €3.99/мес | 128 GB SSD — в 3 раза больше диска |
| RackNerd (sale) | 1 vCPU / 1 GB | ~$1/мес | Минимум, US only |
| Yandex Cloud | 2 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 — это не статический сайт и не блог. Это агент с правами на файловую систему, сеть и выполнение команд. Если кто-то получит к нему доступ, он сможет:
- Украсть API-ключи LLM — а это реальные деньги. Злоумышленник гоняет токены на свой счёт, пока вы спите.
- Читать и изменять код в рабочих копиях репозиториев — вставить бэкдор, украсть интеллектуальную собственность.
- Выполнять произвольные команды на сервере — сервер становится точкой входа в остальную инфраструктуру.
- Получить доступ к MCP-серверам — а там могут быть подключения к базам данных, внешним API, внутренним сервисам.
Плюс объективная реальность: любой публичный IP сканируется ботами в течение минут после создания. Брутфорс SSH, сканирование открытых портов, поиск уязвимых сервисов — это фоновый шум интернета, не направленная атака. Защита нужна не от хакера-профи, который целенаправленно охотится за вами, а от автоматизированных сканеров, которые стучатся во все двери подряд.
Обычный веб-сервис — умеренный риск. AI-агент с правами на файловую систему и API-ключами — высокий риск. Поэтому защита тут в три слоя, а не один пароль.
Три слоя защиты
| Слой | Что защищает | Инструмент |
|---|---|---|
| Сеть | Доступ к порту 4096 из интернета | Tailscale + ufw |
| Приложение | Доступ к Web UI | OAuth через Yandex ID |
| ОС | Доступ по SSH | Ключи вместо паролей, fail2ban, автообновления |
Идея простая: даже если один слой пробит, следующие сдерживают атаку. Атакующий должен пройти через Tailscale (не зная ваших устройств), затем через OAuth (не имея вашего Яндекс-аккаунта), и только потом попадает к opencode-web.
Цепочка защиты сверху вниз:
1. Интернет ↓2. Tailscale — только ваши устройства ↓3. ufw — только трафик с tailscale0 ↓4. OAuth — только вы (Yandex ID) ↓5. opencode-web :4096 ↓6. SSH — ключи + fail2banTailscale: приватная сеть вместо открытых портов
Первое правило: не открывайте порты наружу. Никаких 0.0.0.0:4096 в интернет. Вместо этого — Tailscale.
Tailscale — это mesh-VPN на базе WireGuard. Бесплатно до 100 устройств. Вы ставите клиент на VPS и на телефон — и они оказываются в одной приватной сети. После этого opencode-web слушает 0.0.0.0, но файрвол (ufw) пропускает трафик только с интерфейса tailscale0:
ufw allow in on tailscale0ufw --force enableТеперь сервер виден только вашим устройствам в Tailscale-сети. Телефон, ноутбук, планшет — подключаются по внутреннему IP вида 100.x.x.x:4096.
Настройка Tailscale на сервере — одна команда:
curl -fsSL https://tailscale.com/install.sh | shtailscale upПосле этого открываете ссылку в браузере, авторизуетесь — и сервер в сети. На телефоне устанавливаете приложение Tailscale (App Store / Play Market) и логинитесь тем же аккаунтом.
Аутентификация через Yandex ID
Сам OpenCode Web поддерживает HTTP basic auth. Но для личного сервера хочется нормальную аутентификацию — без запоминания ещё одного пароля и с двухфакторкой из коробки.
Важно: если вы используете Tailscale и доверяете всем устройствам в своей сети — аутентификация не обязательна. Приватная сеть сама по себе уже отсекает внешний мир. Но я решил добавить OAuth как дополнительный слой.
Схема получилась такой:
Браузер ↓ TailscaleCaddy :443 (reverse proxy, HTTPS) ↓auth-proxy (JS, 165 строк) ↓ проверка токена ├─ Yandex ID OAuth └─ opencode-web :4096Caddy работает как reverse proxy с автоматическим HTTPS (Let’s Encrypt). Я привязал к серверу домен второго уровня — это даёт нормальный сертификат и человекочитаемый URL вместо http://100.x.x.x:4096.
Auth proxy — это тонкая прослойка на JavaScript, 165 строк кода. Я попросил OpenCode написать её. Она делает ровно одну вещь: проверяет OAuth-токен Yandex ID перед тем, как пропустить запрос к opencode-web. Никакой логики, кроме аутентификации.
Алгоритм:
- Регистрируете OAuth-приложение в Яндекс ID — получаете
client_idиclient_secret - Callback URL ведёт на ваш сервер — после входа Яндекс редиректит обратно с токеном
- Auth proxy проверяет токен через API Яндекса и либо пускает к opencode-web, либо возвращает 401
Почему Yandex ID:
- Не нужно создавать отдельные пароли — входите по Яндекс-аккаунту
- Двухфакторная аутентификация из коробки
- OAuth-токены короткоживущие, refresh-токены можно отзывать
- Поддерживает PKCE — безопасный flow для браузерных клиентов
Повторюсь: без OAuth можно обойтись. Tailscale уже даёт достаточную изоляцию. Но если хочется красивый URL с доменом и нормальный HTTPS — Caddy + auth proxy решают эту задачу.
SSH-харденинг и fail2ban
Несколько обязательных настроек на самом VPS:
# Только ключи, без паролей, без root-логинаsed -i 's/^#*PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_configsed -i 's/^#*PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_configsed -i 's/^#*PubkeyAuthentication.*/PubkeyAuthentication yes/' /etc/ssh/sshd_configsystemctl restart sshdПлюс fail2ban для защиты от брутфорса SSH:
apt install -y fail2bansystemctl enable --now fail2banИ автоматические security-обновления, чтобы не пропустить критические патчи:
apt install -y unattended-upgradesОсновные концепции настройки
Я не буду публиковать полный setup-скрипт — он зависит от вашего провайдера и предпочтений. Вместо этого разберу ключевые шаги, чтобы вы понимали, что происходит.
Система: пользователь и зависимости
Первое правило — не запускайте opencode от root. Создайте отдельного пользователя:
adduser --gecos "" --disabled-password developerusermod -aG sudo developerИз пакетов понадобятся: curl, ufw, fail2ban, unattended-upgrades, jq. Всё ставится одной командой:
apt update && apt install -y curl ufw fail2ban unattended-upgrades jqУстановка OpenCode и конфигурация
OpenCode ставится официальным установщиком от имени созданного пользователя:
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 ServerAfter=network.target
[Service]Type=simpleWorkingDirectory=%hExecStart=/home/developer/.local/bin/opencode web --port 4096 --hostname 0.0.0.0Restart=on-failureRestartSec=5
[Install]WantedBy=default.targetВажный нюанс: пользовательский systemd требует lingering — иначе сервис умирает при выходе пользователя:
loginctl enable-linger developerПосле этого запускаем:
su - developer -c "systemctl --user daemon-reload"su - developer -c "systemctl --user enable --now opencode-web"Проверяем, что сервер отвечает:
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:
opencode attach http://100.x.x.x:4096Это даёт полноценный TUI-интерфейс, который работает с тем же бэкендом. Можно продолжить сессию, начатую с телефона, или наоборот — начать в терминале, а продолжить в браузере.
Зачем это нужно: TUI удобнее для интенсивной работы с кодом (клавиатура, быстрая навигация). Web UI — для быстрых вопросов с телефона. Сессии общие.
API из коробки
Неочевидный бонус: opencode web поднимает тот же REST API, что и opencode serve. Клиенты (TUI, Web UI) работают через него же. Это значит, что вы можете автоматизировать работу с агентом:
- Запустить агента по расписанию:
opencode run --attach http://100.x.x.x:4096 "проверь PR и оставь ревью" - Написать скрипт для nightly-задач
- Интегрировать с CI/CD: агент проверяет diff перед деплоем
По сути, вы получаете AI-воркера, который живёт на вашем сервере и доступен через API в любой момент. Не нужно поднимать отдельный инстанс для каждой задачи — один сервер обслуживает все сценарии.
Вывод: стоит ли игра свеч
Я пользуюсь этой связкой уже несколько недель. Вот честный расклад.
Производительность: на конфигурации 2 vCPU / 8 GB RAM opencode-web работает с большим запасом. Средняя утилизация CPU — 20%, даже с учётом активной разработки и операций с git. Падений и тормозов не было.
Плюсы:
- AI в кармане. Задать вопрос агенту с телефона в метро или кафе — это реально удобно. Особенно когда нужно быстро проверить идею или вспомнить синтаксис.
- Свой ключ, свой сервер. Вы платите провайдеру LLM напрямую — никаких SaaS-наценок за «удобный интерфейс».
- Три в одном. Web UI, TUI и API работают с одним бэкендом. Начал в терминале — продолжил с телефона.
- API для автоматизации. Можно встроить агента в свои рабочие процессы.
Минусы и ограничения:
- 4 800 ₽/мес за сервер (Yandex Cloud, с запасом) или от €3.79/мес (Hetzner, минимально). Это дополнительный расход, помимо оплаты LLM-токенов.
- Настройка требует времени. Пара часов на установку и отладку, если вы никогда не работали с VPS и Tailscale.
- Не IDE. OpenCode не заменяет Cursor или Copilot для инлайн-автодополнения в редакторе. Это другой сценарий — агентные задачи, а не автокомплит.
Когда это имеет смысл:
- Вы активно пользуетесь AI-агентами и хотите доступ с разных устройств
- У вас уже есть свой API-ключ к LLM-провайдеру, и вы не хотите платить SaaS-надбавку
- Вам нужен AI-воркер для автоматизации (проверка PR, nightly-задачи)
Когда проще взять готовое:
- Вам нужен только инлайн-автокомплит в IDE — берите Cursor или Copilot
- Вы готовы платить за удобство и не хотите возиться с сервером — Claude Code on the web
- Вам нужен AI раз в неделю — неоправданно держать сервер ради этого
Я для себя ответил однозначно: да, стоит. Возможность достать телефон и спросить агента о чём угодно — с моими ключами, моими MCP-серверами, моей конфигурацией — перевешивает затраты на сервер.