VPSРейтинг
AI и нейросети2 сентября 2026 · 14 мин

OpenCode и Goose: ИИ-агент для кода на своём сервере

Агент для работы с кодом — это программа, которая по задаче, поставленной словами, сама читает файлы, правит их и выполняет команды. На ноутбуке такая работа обрывается вместе с закрытой крышкой. На сервере — нет. Разбираем, какой из открытых агентов выбрать, как его поставить и как ограничить ему права.

Зачем агенту отдельный сервер

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

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

Этот довод подробно разобран в статье про Claude Code на VPS. Разница в том, что Claude Code привязан к одному поставщику моделей, а OpenCode и Goose — открытые программы, которые работают с ключом любого поставщика и с моделью, запущенной на вашем же сервере. Именно поэтому их ставят на арендованную машину чаще: менять модель можно, не меняя привычек.

OpenCode, Goose или OpenHands

Открытых агентов много, но всерьёз выбирают из трёх. Разница между ними не в качестве ответов — оно зависит от модели, — а в том, как они устроены и что требуют от сервера.

АгентКак устроенКогда брать
OpenCodeMIT, 1.18.26Один исполняемый файл. Работает в терминале, при желании открывает тот же интерфейс в браузере. Зависимостей нет.Основной случай: живая работа над проектом с подключением по SSH.
GooseApache 2.0, 1.48.0Тоже один файл, но легче по памяти. Умеет сохранять задачу в файл-рецепт и выполнять её без человека за терминалом.Повторяющиеся задачи без участия человека: отчёт, разбор журналов, проверка изменений.
OpenHandsMITВеб-приложение в Docker. Каждую задачу выполняет в отдельном контейнере, для этого ему отдают сокет Docker.Нужна изоляция каждой задачи и интерфейс для нескольких человек.

Дальше в статье основной — OpenCode: он ставится за минуту и не требует ни Docker, ни Node.js. Goose разобран отдельным разделом ниже, потому что закрывает другую задачу — работу по расписанию. OpenHands мы не рассматриваем: доступ к сокету Docker равносилен правам администратора на всём сервере, и ради изоляции задач вы отдаёте агенту машину целиком.

Что за проекты и кому принадлежат

OpenCode развивает компания Anomaly — та же команда, что делает средство разработки SST; репозиторий раньше лежал по адресу sst/opencode. На сентябрь 2026 у него около 203 000 звёзд на GitHub. Goose начинал в компании Block, а в апреле 2026 передан в Agentic AI Foundation — организацию Linux Foundation, куда вошли также протокол MCP и соглашение AGENTS.md; звёзд около 53 800. Обе программы бесплатны целиком, платных изданий у них нет.

Что понадобится

  • Сервер с Ubuntu 22.04 или 24.04, доступ по SSH. Сам агент нетребователен: в наших замерах он занимал около 300 МБ памяти в покое и 500–550 МБ во время задачи. Память нужна не ему, а проекту — сборке, тестам, базе данных рядом.
  • Место на диске. Каждая из двух программ занимает около 300 МБ вместе со вспомогательными файлами. Остальное уходит на сам проект и его зависимости.
  • Доступ к модели. Либо ключ поставщика, которым вы уже пользуетесь, либо бесплатные модели, доступные в OpenCode сразу после установки — их хватит, чтобы проверить работу. Локальная модель на сервере без видеокарты для агента не подходит, и ниже объясняется почему.

Если сервера ещё нет

4 ГБ RAM · 40 ГБ диска

Четыре гигабайта памяти взяты не под агента, а под то, что он будет запускать: установку зависимостей, сборку и тесты проекта. Если сервер отведён только под правку конфигураций и небольших сценариев, хватит и двух гигабайт. Диск от 40 ГБ даёт запас на сам проект: агент часто ставит пакеты и оставляет промежуточные файлы.

В каталоге под эти требования подходят 83 тарифа, самый дешёвый — 720 ₽/мес (HostKey, 4 ГБ, 60 ГБ NVMe).

Открыть каталог с этими фильтрами →

Шаг 1. Отдельный пользователь

Агента запускают не от имени администратора. Сначала ставим то, что понадобится в работе, потом создаём отдельного пользователя и переносим ему ваш открытый ключ, чтобы заходить по SSH сразу под ним:

выполняется от вашего обычного пользователя с правами sudo
sudo apt update && sudo apt install -y curl git tmux

sudo useradd -m -s /bin/bash agent
sudo mkdir -p /home/agent/.ssh
sudo cp ~/.ssh/authorized_keys /home/agent/.ssh/
sudo chown -R agent:agent /home/agent/.ssh
sudo chmod 700 /home/agent/.ssh
sudo chmod 600 /home/agent/.ssh/authorized_keys

Если на сервер вы заходите по паролю, файла ~/.ssh/authorized_keys у вас нет и команда копирования выдаст ошибку. Тогда откройте /home/agent/.ssh/authorized_keys в редакторе и вставьте туда свой открытый ключ (~/.ssh/id_ed25519.pub на вашем компьютере) — права на файл те же.

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

Дальше все команды выполняются на сервере под этим пользователем:

с вашего компьютера
ssh agent@ВАШ_IP

Шаг 2. Установка OpenCode

Установка выполняется от пользователя agent, права администратора не нужны:

curl -fsSL https://opencode.ai/install | bash

Скрипт кладёт один файл в ~/.opencode/bin/opencode и дописывает строку с путём в ~/.bashrc. Ни Node.js, ни Docker, ни компилятор не требуются — всё нужное уже внутри файла.

Сразу после установки команда не найдётся

Новый путь подхватывается только в следующем сеансе. Выйдите и зайдите заново или выполните exec bash -l — после этого opencode --version покажет версию, у нас это 1.18.26.

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

opencode models
opencode run --model opencode/big-pickle "Ответь одним словом: сколько будет 2+2?"

Пришёл ответ — установка закончена. Дальше стоит помнить о двух особенностях бесплатных моделей. Они общие для всех: скорость непредсказуема (один и тот же вопрос у нас обработался за 9, 17 и 166 секунд на трёх разных моделях), а при большом количестве обращений вместо ответа возвращается сообщение о превышении лимита — тогда берут другую модель из списка или подключают свой ключ. И, по документации сервиса, содержимое запросов к бесплатным моделям может использоваться для их улучшения — на закрытом коде их лучше не пробовать.

Шаг 3. Подключение модели

Для работы над своим проектом подключается ключ поставщика. Команда открывает список, в котором выбирают поставщика и вставляют ключ; то же самое делает команда /connect, набранная внутри интерфейса агента:

opencode auth login

Модель по умолчанию задаётся в файле настроек, который создаётся при установке. Точное имя модели берётся из вывода opencode models — оно всегда в формате «поставщик/модель»:

~/.config/opencode/opencode.jsonc
{
  "$schema": "https://opencode.ai/config.json",
  "model": "opencode/big-pickle"
}

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

Локальная модель: честная оценка

OpenCode умеет обращаться к Ollama на этом же сервере — настройка занимает несколько строк, и никаких дополнительных пакетов ставить не нужно, недостающее OpenCode догрузит сам:

~/.config/opencode/opencode.jsonc
{
  "$schema": "https://opencode.ai/config.json",
  "provider": {
    "ollama": {
      "npm": "@ai-sdk/openai-compatible",
      "name": "Ollama",
      "options": { "baseURL": "http://127.0.0.1:11434/v1" },
      "models": {
        "qwen3:1.7b": { "name": "Qwen3 1.7B" }
      }
    }
  }
}

После этого модель появляется в списке как ollama/qwen3:1.7b. Настройка работает, а вот результат разочаровывает. Мы проверили это на сервере без видеокарты с четырьмя ядрами: скорость составила около шести токенов в секунду, и за десять минут агент не справился с задачей «прочитай файл из одной строки и скажи, что он делает» — трижды перечитал файл и в итоге ошибся в формате вызова инструмента.

Дело не только в скорости. Агент передаёт модели описание своих инструментов — это около двух тысяч токенов ещё до вашей задачи, а Ollama на процессоре по умолчанию отводит под весь разговор 4096 токенов (меняется переменной OLLAMA_CONTEXT_LENGTH, но каждый шаг увеличения требует памяти). Вывод простой: на сервере без видеокарты локальную модель для агента брать не стоит.

Шаг 4. Первый запуск и права агента

Агент работает с тем каталогом, из которого запущен. Забираем проект на сервер и запускаем:

mkdir -p ~/projects && cd ~/projects
git clone https://github.com/ваш-логин/myapp.git
cd myapp
opencode

Открывается интерфейс в терминале. Внизу экрана указан текущий режим и модель — например, Build · Big Pickle. Клавиша Tab переключает режим,Ctrl+P открывает список команд. Режимов два, и разница между ними принципиальна: Plan только читает код и отвечает, ничего не меняя,Build — правит файлы и выполняет команды. Первую задачу в незнакомом проекте разумно ставить в режиме Plan.

По умолчанию агенту разрешено почти всё, кроме чтения файлов с переменными окружения (.env). Правила задаются разделом permission в том же файле настроек: разделы model, provider и permission живут в нём рядом, отдельных файлов заводить не нужно. Разумный набор для начала:

~/.config/opencode/opencode.jsonc
{
  "$schema": "https://opencode.ai/config.json",
  "permission": {
    "bash": {
      "*": "ask",
      "git *": "allow",
      "npm run *": "allow",
      "rm *": "deny",
      "sudo *": "deny"
    },
    "external_directory": "deny"
  }
}

Читается это так: любую команду агент спрашивает, работу с системой контроля версий и запуск сценариев проекта выполняет молча, удаление файлов и попытки повысить права запрещены совсем, выход за пределы каталога проекта — тоже. Мы проверили запрет на живой установке: команда не выполняется, а агенту возвращается отказ с текстом сработавшего правила. Значение ask имеет смысл только в живом сеансе: в неинтерактивном режиме opencode run подтверждать запрос некому, и он автоматически отклоняется.

Шаг 5. Долгие задачи и доступ из браузера

Если запустить агента прямо в сеансе SSH, обрыв связи прервёт задачу. Запускайте его внутри tmux — программы, которая держит сеанс терминала на сервере независимо от вашего подключения:

tmux new -s agent      # создать сеанс и работать в нём
# отсоединиться: Ctrl+B, затем D
tmux attach -t agent   # вернуться в него с любого устройства

Второй способ работы — тот же интерфейс в браузере. На сервере его поднимает команда opencode serve: она слушает только адрес 127.0.0.1 и наружу ничего не отдаёт. Пароль задаётся переменной окружения, имя пользователя по умолчанию — opencode. Сгенерируем пароль, сохраним его в файл и запустим:

openssl rand -base64 24 > ~/.opencode-password
chmod 600 ~/.opencode-password

cd ~/projects/myapp
OPENCODE_SERVER_PASSWORD=$(cat ~/.opencode-password) opencode serve --port 4096

Чтобы интерфейс поднимался сам после перезагрузки, оформим его службой. Проверочный запуск при этом надо остановить клавишами Ctrl+C, иначе порт окажется занят. Пароль — тот же, что в файле выше; кладём его туда, где его прочитает только администратор:

/etc/opencode.env — затем sudo chmod 600 /etc/opencode.env
OPENCODE_SERVER_PASSWORD=строка_из_файла_.opencode-password
/etc/systemd/system/opencode.service
[Unit]
Description=OpenCode server
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=agent
WorkingDirectory=/home/agent/projects/myapp
EnvironmentFile=/etc/opencode.env
ExecStart=/home/agent/.opencode/bin/opencode serve --port 4096
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now opencode

Со своего компьютера порт пробрасывается туннелем SSH, после чего интерфейс открывается по адресу http://127.0.0.1:4096 в обычном браузере:

выполняется на вашем компьютере, окно оставить открытым
ssh -N -L 4096:127.0.0.1:4096 agent@ВАШ_IP

Не открывайте этот порт наружу

У serve есть параметр --hostname 0.0.0.0, который выставляет интерфейс в интернет. Делать этого не нужно: через него выполняются команды на сервере, и единственная защита — пароль в переменной окружения. Туннель SSH даёт тот же результат без открытого порта.

Goose: когда он подходит лучше

Goose решает ту же задачу, но у него есть две особенности, ради которых его ставят рядом. Первая — вес: в наших замерах он занимал около 110 МБ памяти против примерно 500 МБ у OpenCode. Вторая важнее — задачу можно сохранить в файл-рецепт и выполнять её без человека за терминалом, по расписанию.

Установка требует одного пакета, иначе архив не распакуется:

sudo apt install -y bzip2
curl -fsSL https://github.com/aaif-goose/goose/releases/download/stable/download_cli.sh | CONFIGURE=false bash

Программа кладётся в ~/.local/bin/goose; как и в случае с OpenCode, путь подхватывается при следующем входе. Переменная CONFIGURE=false отключает интерактивную настройку — на сервере её удобнее заменить двумя файлами. Первый задаёт поставщика и модель, второй хранит ключ:

~/.config/goose/config.yaml — имя модели берётся из документации поставщика
GOOSE_PROVIDER: anthropic
GOOSE_MODEL: claude-sonnet-5
~/.config/goose/secrets.yaml — обязательно chmod 600
ANTHROPIC_API_KEY: ваш_ключ

Мы проверили: ключ из этого файла подхватывается, отдельная команда настройки не нужна. Локальная модель подключается так же просто — GOOSE_PROVIDER: ollama и OLLAMA_HOST: http://127.0.0.1:11434, с теми же оговорками про скорость, что и выше.

Разовая задача без сохранения истории выполняется одной командой:

cd ~/projects/myapp
goose run --no-session -t "Проверь, что все зависимости в package.json используются"

Ради чего всё затевалось — повторяющаяся задача. Она описывается файлом-рецептом, в котором обязательно поле prompt: без него запуск без человека завершается ошибкой no text provided for prompt in headless mode.

~/recipes/deps.yaml
version: 1.0.0
title: Проверка зависимостей
description: Ищет неиспользуемые пакеты в проекте
instructions: Ты работаешь в каталоге проекта и отвечаешь коротко, списком.
prompt: Найди в package.json пакеты, которые нигде не импортируются, и выведи их списком.
goose run --no-session --recipe ~/recipes/deps.yaml

Когда рецепт отработал вручную, его ставят на расписание. Расписание задаёт системный cron: crontab -e под пользователем agent и одна строка. Пути указываются полностью — у cron своё короткое значение PATH, и короткое имя команды он не найдёт:

crontab пользователя agent: каждый понедельник в 9:00
0 9 * * 1 cd /home/agent/projects/myapp && /home/agent/.local/bin/goose run --no-session --recipe /home/agent/recipes/deps.yaml >> /home/agent/deps.log 2>&1

Почему не встроенное расписание goose

У Goose есть своя команда goose schedule add, и она действительно записывает задание — goose schedule list показывает его в списке. Но выполнять задания некому: встроенный планировщик живёт внутри запущенного приложения, а на сервере оно не запущено. Мы проверили: задание с расписанием «каждую минуту» даже через полторы минуты оставалось со строкой Last Run: Never, в том числе при работающем goose serve. Поэтому на сервере расписание отдают cron.

Что агент может на самом деле

Правила permission ограничивают агента, но не превращают его в песочницу. Модель решает, какую команду вызвать, а выполняется команда от имени пользователя agent со всеми его правами. Простое правило: считайте, что всё доступное этому пользователю доступно и агенту.

  • Никакого sudo. Права администратора агенту не нужны ни для одной задачи по коду. Если пакет действительно нужен системе — поставьте его сами.
  • Ключи от других серверов — не здесь. В домашнем каталоге этого пользователя не должно быть ни ключей от рабочих серверов, ни доступов к базам с настоящими данными.
  • Проект — копия репозитория. Работайте в клоне репозитория и регулярно смотрите git diff. Это единственный способ отличить нужную правку от лишней.
  • Порт агента не выставляется в интернет. Только адрес 127.0.0.1 и туннель SSH.
  • Чужой код — отдельный сервер. Если проект принадлежит клиенту, дешевле поднять отдельную машину, чем разбираться потом, что именно агент прочитал.

Более строгая изоляция — запуск агента внутри контейнера, из которого виден только каталог проекта. Это уменьшает ущерб от ошибки, но добавляет работы: контейнеру придётся отдать всё, что нужно проекту, — язык, пакеты, сеть. Описанный выше вариант — отдельный пользователь без прав администратора — закрывает большую часть рисков и не мешает работать. Общие настройки сервера разобраны в статье о базовой безопасности VPS.

Частые проблемы

opencode: command not found сразу после установки

Установка прошла, но путь к программе добавлен в ~/.bashrc, а текущий сеанс этот файл уже прочитал. Выйдите и зайдите заново либо выполните exec bash -l. То же самое относится к Goose: он ставится в ~/.local/bin, который добавляется в путь при входе в систему. Важное следствие: ~/.bashrc читается только для сеанса с клавиатурой, поэтому в сценариях, службах и заданиях cron команду всегда пишут полным путём — /home/agent/.opencode/bin/opencode.

opencode web на сервере выдаёт ошибку xdg-open

Команда web рассчитана на настольную систему: она поднимает интерфейс и сразу пытается открыть браузер. На сервере браузера нет, и вместо запуска выводится сообщение Executable not found in $PATH: xdg-open. Сам интерфейс при этом работает, но пугающее сообщение остаётся в журнале. На сервере используйте opencode serve --port 4096 — интерфейс тот же, попытки открыть браузер нет.

Локальная модель бесконечно перечитывает один и тот же файл

Это не ошибка настройки, а нехватка возможностей модели. Небольшие модели путаются в вызове инструментов и зацикливаются, а короткий предел разговора (у Ollama на процессоре по умолчанию 4096 токенов) вытесняет начало задачи из памяти модели. Увеличьте предел переменной OLLAMA_CONTEXT_LENGTH и возьмите модель покрупнее — но на сервере без видеокарты это упирается в скорость. Рабочее решение — внешняя модель по ключу.

Установка Goose обрывается: bzip2 is required but not installed

В минимальном образе Ubuntu этого архиватора нет, а установочный скрипт им распаковывает архив. Поставьте sudo apt install -y bzip2 и повторите установку. После неудачной попытки в домашнем каталоге остаётся скачанный архив goose-x86_64-unknown-linux-gnu.tar.bz2 — его можно удалить.

Коротко: порядок действий

  1. Отдельный пользователь agent без прав администратора, вход по ключу.
  2. curl -fsSL https://opencode.ai/install | bash, затем перезайти в систему.
  3. Проверка бесплатной моделью: opencode run --model opencode/big-pickle.
  4. Свой ключ через opencode auth login, модель по умолчанию — в настройках.
  5. Правила permission: удаление и sudo запрещены, остальное спрашивается.
  6. Работа в tmux, чтобы обрыв связи не прерывал задачу.
  7. Браузерный интерфейс — opencode serve --port 4096 и туннель SSH.
  8. Goose ставится рядом, если нужны повторяющиеся задачи: рецепт и строка в cron.

Частые вопросы

Отдельная машина под агента — тот случай, когда проект остаётся на своём сервере, а агенту достаётся только рабочая копия репозитория. Сборки и тестов на ней нет, поэтому требования падают до 2 ГБ памяти и 20 ГБ диска.

Под эти требования в каталоге подходит 108 тарифов, от 429 ₽/мес (AdminVPS, 2 ГБ, 30 ГБ NVMe).

Тарифы от 2 ГБ RAM