DeepSeek Harness на VPS: безпечно через SSH
Як встановити DeepSeek Harness на Linux VPS, зафіксувати версію npm, зрозуміти можливості plugin і відкрити web UI на порту 3080 через SSH tunnel.
Що таке DeepSeek Harness
DeepSeek Harness (dsh) — це середовище виконання агентів Node.js, яке можна запустити на VPS (virtual private server). Безпечний спосіб запуску — прив’язати його до 127.0.0.1, а підключатися з браузера через SSH (secure shell) tunnel. Він надає web UI (user interface) на порту 3080 замість роботи в терміналі. Цей web server не має власної автентифікації за паролем. Тому відкритий порт 3080 надає кожному, хто його знайде, доступ до агента, який читає ваші файли та виконує команди від імені вашого користувача Linux.
DeepSeek випустила його 13 August 2026 року за ліцензією MIT як npm package @deepseek-ai/dsh. Проєкт описує себе як developer preview і зазначає, що слід очікувати змін, які порушують сумісність. Усі номери версій нижче відповідають стану на August 2026 року. Перед копіюванням цих даних на важливий сервер перевірте repository.
Усю архітектуру об’єднує одна ідея: усе є plugin. Адаптер моделі, реєстр інструментів, журнал сесій, sandbox, scheduler і сам agent loop — це plugins, завантажені в один спільний context, і будь-який із них можна замінити. Немає привілейованого ядра, яке plugins лише розширюють. Саме це робить harness вартим випробування, але водночас саме тут міститься єдиний реальний ризик.
Harness — це не модель
Harness запускає цикл роботи агента. Логіка міркування виконується в моделі в іншому місці. Тому нічого не працюватиме, доки ви не вкажете API-ключ (application programming interface) або адресу кінцевої точки моделі, яку розгорнули самостійно.
Це налаштовується в UI у розділах Settings, а потім Models. Каталог містить готові картки для основних API-провайдерів (DeepSeek, OpenAI, Anthropic), у яких потрібно вставити ключ. Цікавий варіант — "Add a custom provider": він приймає ідентифікатор провайдера, відображуване ім’я, базову URL-адресу, API-протокол і облікові дані та працює за OpenAI-compatible протоколом. Тому підходить будь-який шлюз або локальний сервер, що реалізує цей протокол. Custom providers також можуть звертатися до OpenAI-compatible кінцевої точки GET /models, щоб автоматично отримати список моделей.
Так harness підключається до моделі на тому самому VPS. Ollama надає OpenAI-compatible API за адресою http://127.0.0.1:11434/v1/. У полі API key потрібно вказати будь-який рядок, за домовленістю ollama, оскільки це поле є обов’язковим, але його значення ігнорується. Складніше визначити, чи достатньо якісною буде модель, яка поміщається у ваш VPS, для керування агентом. Відмінності між Ollama і vLLM як локальними серверами моделей визначають, скільки оперативної пам’яті потребуватиме цей вибір: відмінності між Ollama і vLLM як локальними серверами моделей.
Ключі, введені в UI, доступні лише для запису. Harness зберігає їх у $DSH_HOME/.credentials.yaml, а в settings.yaml зберігає лише посилання на облікові дані. Значення $DSH_HOME за замовчуванням — ~/.dsh. Ставтеся до цього файла як до файла з паролями, оскільки це саме так: кожен, хто прочитає його, зможе витрачати кошти з вашого API-бюджету.
Що потрібно підготувати перед встановленням
- VPS з Ubuntu 24.04 або іншим актуальним Linux і доступом через SSH
- Node.js 22.19 або новішої версії з лінійки 22.x, або Node.js 24 і новішої версії — саме на цих версіях проєкт збирається та проходить тести
- звичайний обліковий запис, а не
root, оскільки агент виконує shell-команди від імені користувача, який запустив процес pnpmу PATH, якщо плануєте встановлювати плагіни, оскільки команда плагіна запускає його як зовнішню команду- закритий порт 3080 у вашому firewall і в окремому мережевому firewall провайдера
Власний пакет nodejs в Ubuntu старіший за версію, потрібну harness, тому встановлюйте Node через NodeSource або nvm, а не використовуйте apt install nodejs. Якщо VPS щойно створено, спочатку посилити захист SSH варто протягом десяти хвилин, оскільки тунель, від якого ви зараз залежатимете, захищений не краще за SSH-сервер, через який він працює.
Встановлення DeepSeek Harness на VPS із фіксацією версії
node --version
npx @deepseek-ai/dsh@0.1.0-rc.6 webnpx завантажує пакет і запускає його двійковий файл dsh. web — це псевдонім для --profile web, який запускає браузерний застосунок, а процес виводить адресу, на якій він прослуховує з’єднання. Значення за замовчуванням — http://127.0.0.1:3080.
Зафіксуйте версію. npx @deepseek-ai/dsh web щоразу визначає, на що в момент запуску вказує тег latest, а проєкт уже випустив кілька release candidate і попереджає про майбутні несумісні зміни. 0.1.0-rc.6 — це значення, на яке latest вказував 13 August 2026. Фіксована версія гарантує, що сервер, налаштований сьогодні, працюватиме так само наступного місяця. Оновлення стане свідомим рішенням, а не випадковою зміною.
Для щоденного використання встановіть пакет один раз, а не визначайте версію заново під час кожного запуску.
npm install -g @deepseek-ai/dsh@0.1.0-rc.6
dsh --profile web --helpДругий рядок варто виконати, оскільки launcher і вебзастосунок мають окремі набори прапорців. dsh --help показує власні параметри launcher. dsh --profile web --help показує прапорці, які приймає вебзастосунок. Саме серед них є --port, --host і повторюваний параметр --trusted-host.
Тепер перевірте, на якій адресі процес прослуховує з’єднання.
ss -tlnp | grep 3080У стовпці локальної адреси має бути 127.0.0.1:3080. Якщо там указано 0.0.0.0:3080, інтерфейс доступний з інтернету. Зупиніть процес, перш ніж робити щось інше.
Чому порт 3080 не можна публікувати
Вебсервер не має шару автентифікації. Його конфігурація визначає адресу прослуховування та порт прослуховування, і на цьому весь захист закінчується. Керування доступом для розгортань не на loopback-інтерфейсі здійснюється окремим параметром trusted host, який не є формою входу.
Тепер врахуйте, що працює за цим портом. Агент редагує файли у робочому просторі та виконує shell-команди, а облікові дані вашого провайдера зберігаються на диску поруч із ним. Отже, відкритий порт 3080 — це віддалена shell-оболонка з chat-інтерфейсом, яка працює від імені користувача, що її запустив, і має доступ до вашого API key. Для цього не потрібен експлойт. Достатньо знати номер порту, а сканери знаходять номери портів протягом кількох годин після появи хоста в мережі.
CLI (command line interface) це підтверджує. Починаючи з 0.1.0-rc.6, він навмисно не підтримує --host 0.0.0.0 і завершує роботу з помилкою використання замість запуску. Ця відмова є функцією захисту, тому не шукайте патч, який її прибирає.
Є ще два прийнятні варіанти розгортання, якщо тунель вам не підходить. Розмістіть сервер у приватній overlay-мережі, щоб він мав адресу, до якої могли маршрутизувати трафік лише ваші пристрої. Саме це забезпечує self-hosted control server Headscale. Або розмістіть перед ним reverse proxy, який автентифікує запит до його надходження на порт 3080, наприклад single sign-on server Authentik із forward auth. Reverse proxy без автентифікації перед ним не є засобом захисту. Це лише довший URL.
Доступ до вебінтерфейсу через SSH-тунель
Виконайте це на своєму ноутбуці, а не на сервері.
ssh -N -L 3080:127.0.0.1:3080 you@your-server-L відкриває порт 3080 на ноутбуці та пересилає все, що підключається до нього, через зашифровану SSH-сесію. Частину 127.0.0.1:3080 обробляє сервер, тому з’єднання надходить до harness із loopback, так, ніби ви працюєте безпосередньо на цій машині. -N означає, що віддалену оболонку запускати не потрібно, оскільки вам потрібне лише перенаправлення порту.
Після цього відкрийте http://127.0.0.1:3080 у локальному браузері. Якщо порт 3080 вже зайнятий на ноутбуці, змініть ліве число: ssh -N -L 3180:127.0.0.1:3080 you@your-server, а потім відкрийте http://127.0.0.1:3180. Число ліворуч є локальним, а число праворуч належить серверу, тому змінюється лише ліве число.
Збережіть це в ~/.ssh/config і більше не вводьте його вручну.
Host dsh
HostName 203.0.113.10
User deploy
IdentityFile ~/.ssh/id_ed25519
LocalForward 3080 127.0.0.1:3080Після цього ssh -N dsh запускає тунель. Повідомлення браузера про відмову в підключенні зазвичай означає, що тунель працює, але на віддаленому боці нічого не прослуховує порт, оскільки SSH пересилає порт незалежно від того, чи запущений harness. Перевірте сервер за допомогою наведеної вище команди ss.
Не зупиняйте harness після виходу із системи
Команда npx завершує роботу разом із shell. Користувацький сервіс systemd продовжує працювати та повторно запускає harness після збою або перезавантаження.
loginctl enable-linger $USER
mkdir -p ~/.config/systemd/user
command -v dshenable-linger важливий, оскільки користувацькі сервіси зазвичай зупиняються після завершення останнього сеансу. Без нього harness завершує роботу одразу після закриття тунелю. Візьміть абсолютний шлях, який виводить command -v dsh, і вкажіть його в unit, оскільки systemd не шукає виконувані файли в PATH, сформованому вашим login shell.
[Unit]
Description=DeepSeek Harness web UI
After=network-online.target
[Service]
Type=simple
WorkingDirectory=%h/projects/site
ExecStart=/usr/local/bin/dsh web
Restart=on-failure
RestartSec=5
[Install]
WantedBy=default.targetWorkingDirectory — це не косметична настройка. Процес dsh використовує поточний каталог як розташування файлової системи за замовчуванням. Тому сервіс, запущений не з того каталогу, передає агенту неправильний робочий каталог за замовчуванням. Робочий каталог усе одно можна вибрати в UI.
systemctl --user daemon-reload
systemctl --user enable --now dsh
systemctl --user status dshЯкщо unit відмовляється запускатися, майже завжди вказано неправильний шлях ExecStart або використовується версія Node, яку бінарний файл не підтримує. Команда journalctl --user -u dsh -n 50 показує, яка саме причина виникла. Такий самий підхід підходить для постійної роботи будь-якого coding agent на VPS, а причини збоїв будуть ідентичними.
Дозволи плагіна
Плагін — це модуль, який додає сервіси, типізовані події та оборотні ефекти до спільного контексту. На розширення варто звернути особливу увагу:
- зареєструвати постачальника моделей у
ctx.llm - додати інструменти для роботи моделі в
ctx.tools - надати бекенд shell для
ctx.shell - надати доступ до файлової системи або політики через
ctx.fs - зареєструвати команди користувача в
ctx.commands - виконувати фонові завдання через
ctx.jobs - обгорнути породжені процеси за допомогою бекенду
ctx.sandbox - перехоплювати запити та виклики інструментів через події
agent/*іtools/* - розширити довготривалий стан сеансу
- керувати UI через
ctx.agents
Прочитайте цей список так, як його прочитав би зловмисник. Плагін може надати шар файлової системи та shell-шар, а також перебувати між моделлю та кожним викликом інструмента. Між плагіном і цими точками інтеграції немає діалогового вікна підтвердження дозволів, оскільки плагін є звичайним кодом Node, завантаженим у той самий процес, що й решта компонентів. Установлення плагіна означає виконання чужого коду з дозволами вашого агента, а дозволи агента — це дозволи вашого Unix-користувача.
Це те саме рішення щодо довіри, яке ви приймаєте, коли підключаєте MCP-сервер до агента на VPS, де MCP — це протокол контексту моделі. Саме тому безпечний запуск агента для програмування на VPS починається з облікового запису, від імені якого він працює, а не з моделі. З цієї ж причини атаки через ланцюг постачання npm настільки небезпечні для серверів: компрометація відбувається на етапі встановлення, і система не показує жодного запиту на підтвердження.
Звідки беруться плагіни
Плагіни зберігаються в профілях. Профіль — це іменована композиція, що зберігається в $DSH_HOME, який за замовчуванням має значення ~/.dsh. Каталог кожного профілю містить плагіни, встановлені за межами основного дерева. CLI керує ними, передаючи ваші аргументи безпосередньо до pnpm і використовуючи каталог профілю як робочий каталог.
dsh plugin --profile web add github:deepseek-harness/turtle-ui
dsh plugin --profile web remove turtle-uiОскільки аргументи передаються до pnpm без змін, add, remove, update і why працюють так само, як у будь-якому проєкті pnpm. Плагіном може бути npm-пакет або посилання на GitHub. pnpm спочатку має бути доступним у PATH. У Node 22 і новіших версіях corepack enable pnpm додає його туди.
Пошук виконується через topic на GitHub. Автори плагінів додають topic dsh-plugin до свого репозиторію, а перегляд цього topic дає змогу знайти доступні плагіни. Topic — це мітка, яку автор додає до власного репозиторію. Ніхто не перевіряє її та не підписує, а сторінка topic сортує репозиторії за кількістю зірок, що показує популярність, а не безпеку.
Чотири правила допомагають зберігати контроль. Прочитайте вихідний код перед встановленням, оскільки більшість плагінів достатньо малі, щоб прочитати їх за десять хвилин. Зафіксуйте точну версію або commit замість відстеження гілки. Запускайте harness від імені користувача, якому більше нічого не належить, на VPS, який ви готові перевстановити. Надайте агенту окремий API key із власним лімітом витрат, відмінним від ключа, який використовують production-сервіси.
Якщо ви хочете спочатку порівняти варіанти архітектури, multi-agent harness Omnigent розв’язує ту саму проблему за іншою схемою, а переваги й компроміси стають очевидними після підключення плагінів.
Що ламається найперше
Node застарілий. Проєкт розрахований на Node 22.19 і новіші версії гілки 22.x або на Node 24 і новіші версії. Це перевіряється в CI. Старіше середовище виконання завершується з помилкою під час запуску, оскільки код використовує відсутні в ньому синтаксис і API. Спочатку виконайте node --version.
Порт 3080 уже зайнятий. Його може використовувати другий harness, застарілий процес або інший застосунок. Знайдіть процес за допомогою ss -tlnp | grep 3080, а потім зупиніть його або запустіть harness на іншому порту за допомогою dsh web --port 3180. --port належить вебзастосунку, тому його потрібно виконувати після web.
Браузер не може підключитися через тунель. Переконайтеся, що ви відкрили 127.0.0.1, а не публічну адресу сервера, оскільки перенаправлений порт існує лише на вашому ноутбуці. Потім переконайтеся, що harness прослуховує порт на сервері. SSH налаштовує перенаправлення незалежно від того, чи приймає щось підключення на віддаленому кінці.
dsh plugin негайно завершується з помилкою. Ця команда є обгорткою навколо pnpm, тому відсутній бінарний файл pnpm зупиняє її ще до початку роботи будь-якого плагіна.
Агент не бачить ваш проєкт. За замовчуванням workspace — це каталог, з якого запущено процес. Тому unit, у якого WorkingDirectory вказує на домашній каталог, надає агенту доступ до домашнього каталогу. Виберіть workspace в UI або виправте unit і перезавантажте його конфігурацію.
FAQ
Чи безпечно відкривати веб-інтерфейс DeepSeek Harness на порту 3080?
Ні. Вебсервер не має власної автентифікації, а агент за ним редагує файли та виконує shell-команди від імені користувача, який запустив процес. Ключ API вашого провайдера зберігається на тому самому диску. Залиште listener на 127.0.0.1 і підключайтеся до нього через SSH-тунель. Також підійде приватна overlay-мережа або reverse proxy, який автентифікує кожен запит до його надходження на порт. Починаючи з версії 0.1.0-rc.6, CLI відхиляє --host 0.0.0.0 і завершує роботу з помилкою використання. Це показує, як автори оцінюють таку конфігурацію.
Чи потрібен мені ключ API DeepSeek, чи можна використовувати локальну модель?
Підійде будь-який варіант, оскільки harness є середовищем виконання, а не моделлю. У розділі Settings, а потім Models можна вставити ключ у картку провайдера з каталогу або вибрати "Add a custom provider" і вказати базову URL-адресу, яка підтримує OpenAI-compatible протокол. Локальний сервер Ollama відповідає на http://127.0.0.1:11434/v1/ і приймає будь-який рядок у полі ключа API. Ключі зберігаються в $DSH_HOME/.credentials.yaml, значенням за замовчуванням для якого є ~/.dsh/.credentials.yaml.
Що насправді отримує плагін після встановлення плагіна DeepSeek Harness?
Права облікового запису, від імені якого працює harness. Плагін є кодом Node, завантаженим у той самий процес. Точки розширення охоплюють shell backend, файловий рівень, реєстр інструментів і події, що обгортають кожен виклик інструмента. Ніщо не ізолює плагін від цих компонентів, якщо сам плагін не надає власний sandbox. Перед встановленням прочитайте вихідний код і запускайте harness від імені користувача, якому не належать важливі для вас дані.
Яку версію слід встановити і чи продовжить вона працювати?
Встановіть точну версію, наприклад npx @deepseek-ai/dsh@0.1.0-rc.6 web. Саме на цю версію вказував тег latest 13 August 2026. Проєкт позиціонується як developer preview і попереджає, що зміни з порушенням сумісності є очікуваними. Тому команда без зафіксованої версії може працювати інакше вже наступного дня. Перевірте репозиторій перед оновленням і враховуйте, що ключі конфігурації та інтерфейси плагінів можуть змінюватися, поки версія все ще починається з 0.