SSD Nodes Learn 🎉 VPS từ $5.50/tháng
Hướng dẫn Matt ConnorBởi Matt Connor

Cài DeepSeek Harness trên VPS và giữ riêng tư

Cài DeepSeek Harness trên Linux VPS, pin version npm, hiểu plugin có thể làm gì và truy cập web UI port 3080 an toàn qua SSH tunnel, không public port.

DeepSeek Harness là gì

DeepSeek Harness (dsh) là một runtime agent Node.js có thể chạy trên VPS (virtual private server). Cách chạy an toàn là bind nó vào 127.0.0.1, rồi truy cập bằng trình duyệt thông qua một SSH (secure shell) tunnel. Nó cung cấp web UI (user interface) trên port 3080 thay vì chạy trong terminal. Web server này không yêu cầu password riêng. Vì vậy, nếu public port 3080, bất kỳ ai phát hiện được port này cũng có thể truy cập một agent có khả năng đọc file và chạy command bằng user Linux của bạn.

DeepSeek phát hành nó vào ngày 13 tháng 8 năm 2026 theo giấy phép MIT, dưới dạng npm package @deepseek-ai/dsh. Dự án tự mô tả là bản xem trước dành cho developer và nêu rõ rằng các thay đổi làm mất tính tương thích là điều có thể xảy ra. Mọi version number bên dưới đều là ảnh chụp trạng thái vào tháng 8 năm 2026. Hãy kiểm tra repository trước khi sao chép bất kỳ nội dung nào lên một máy chủ quan trọng.

Một ý tưởng xuyên suốt toàn bộ thiết kế: mọi thứ đều là plugin. Model adapter, tool registry, session log, sandbox, scheduler và chính agent loop đều là các plugin được load vào một context dùng chung, và bất kỳ thành phần nào cũng có thể được thay thế. Không có một core đặc quyền mà plugin chỉ bổ sung chức năng bên ngoài. Đây là lý do harness đáng để thử, nhưng cũng là nơi chứa rủi ro thực sự duy nhất.

Một harness không phải là model

Harness chạy vòng lặp agent. Phần suy luận diễn ra trong một model ở nơi khác, nên mọi thứ sẽ không hoạt động cho đến khi bạn cung cấp API (application programming interface) key hoặc địa chỉ của một model endpoint do bạn tự host.

Bạn cấu hình phần này trong UI, tại Settings rồi đến Models. Catalog có sẵn các card cho những nhà cung cấp API lớn (DeepSeek, OpenAI, Anthropic), nơi bạn dán key vào. Tùy chọn đáng chú ý là "Add a custom provider": tùy chọn này yêu cầu provider ID, display name, base URL, API protocol và credential, đồng thời sử dụng OpenAI-compatible protocol. Vì vậy, mọi gateway hoặc local server triển khai protocol này đều hoạt động được. Custom provider cũng có thể truy vấn endpoint OpenAI-compatible GET /models để tự điền danh sách model.

Đó là cách trỏ harness đến một model trên cùng VPS. Ollama cung cấp API OpenAI-compatible tại http://127.0.0.1:11434/v1/ và yêu cầu điền API key bằng một chuỗi bất kỳ, theo quy ước là ollama, vì trường này bắt buộc nhưng sau đó bị bỏ qua. Câu hỏi khó hơn là model đủ nhỏ để chạy trên VPS của bạn có đủ khả năng điều khiển một agent hay không. Sự khác nhau giữa Ollama và vLLM khi làm local model server quyết định câu trả lời sẽ tiêu tốn bao nhiêu RAM.

Các key nhập vào UI chỉ có thể ghi. Harness lưu chúng trong $DSH_HOME/.credentials.yaml và chỉ giữ một credential reference trong settings.yaml. $DSH_HOME mặc định là ~/.dsh. Hãy coi file đó như file chứa password, vì đúng là như vậy: bất kỳ ai đọc được file đều có thể tiêu ngân sách API của bạn.

Điều kiện cần có trước khi cài đặt

  • một VPS chạy Ubuntu 24.04 hoặc một bản Linux hiện hành khác, có quyền truy cập SSH
  • Node.js 22.19 trở lên trong nhánh 22.x, hoặc Node.js 24 trở lên; đây là các phiên bản mà dự án dùng để build và test
  • một tài khoản người dùng thông thường, không phải root, vì agent chạy các lệnh shell với quyền của người đã khởi động tiến trình
  • pnpm trong PATH nếu bạn dự định cài plugin, vì lệnh plugin sẽ gọi nó qua shell
  • đóng cổng 3080 trong firewall của bạn và firewall mạng riêng của nhà cung cấp

Gói nodejs của Ubuntu cũ hơn yêu cầu của harness, vì vậy hãy cài Node từ NodeSource hoặc nvm thay vì dùng apt install nodejs. Nếu VPS mới được tạo, hardening SSH trước khi làm việc khác là việc đáng dành mười phút, vì tunnel mà bạn sắp phụ thuộc vào chỉ an toàn khi SSH server phía sau nó được bảo vệ tốt.

Cài DeepSeek Harness trên VPS, cố định một version

node --version
npx @deepseek-ai/dsh@0.1.0-rc.6 web

npx tải package và chạy binary dsh của nó. web là alias của --profile web, lệnh khởi động ứng dụng trình duyệt; sau đó process in ra địa chỉ mà nó đang listen. Mặc định là http://127.0.0.1:3080.

Hãy cố định version. npx @deepseek-ai/dsh web resolve đến giá trị mà tag latest trỏ tới tại thời điểm bạn chạy lệnh, trong khi project đã phát hành một số release candidate và cho biết sẽ có breaking change. 0.1.0-rc.6 là giá trị mà latest trỏ tới vào ngày 13 August 2026. Cố định version giúp máy chủ bạn thiết lập hôm nay hoạt động giống như vào tháng sau. Khi đó, việc upgrade là quyết định có chủ ý thay vì một thay đổi ngoài dự kiến.

Để sử dụng hằng ngày, hãy cài đặt một lần thay vì resolve lại mỗi lần khởi động.

npm install -g @deepseek-ai/dsh@0.1.0-rc.6
dsh --profile web --help

Dòng thứ hai đáng chạy, vì launcher và web app dùng các bộ flag riêng. dsh --help hiển thị các option riêng của launcher. dsh --profile web --help hiển thị các flag mà web app chấp nhận. Đây là nơi có --port, --host và flag có thể lặp lại --trusted-host.

Bây giờ hãy xác nhận process đang listen trên địa chỉ nào.

ss -tlnp | grep 3080

Cột địa chỉ nội bộ phải hiển thị 127.0.0.1:3080. Nếu hiển thị 0.0.0.0:3080, UI có thể truy cập từ Internet. Hãy dừng process trước khi làm bất kỳ việc gì khác.

Vì sao tuyệt đối không được publish port 3080

Web server không có lớp xác thực. Cấu hình của nó chỉ định listen host và listen port, và đó là toàn bộ bề mặt truy cập. Kiểm soát truy cập cho các triển khai không dùng loopback là một setting trusted-host riêng, không phải màn hình đăng nhập.

Tiếp theo, hãy xem những gì nằm sau port đó. Agent chỉnh sửa các file trong workspace và chạy shell command, còn credential của provider được lưu trên disk ngay bên cạnh nó. Vì vậy, port 3080 mở ra thực chất là một remote shell có giao diện chat, chạy dưới user đã khởi động nó và có API key của bạn đi kèm. Không ai cần khai thác lỗ hổng cho việc này. Họ chỉ cần biết số port, và các scanner sẽ tìm ra số port trong vòng vài giờ sau khi host online.

CLI (command line interface) cũng xác nhận điều này. Kể từ 0.1.0-rc.6, CLI cố ý không hỗ trợ --host 0.0.0.0 và thoát với usage error thay vì khởi động. Việc từ chối này là một tính năng, vì vậy đừng tìm patch để gỡ bỏ nó.

Có 2 cách triển khai khác hợp lý khi tunnel không phù hợp. Đưa máy chủ vào private overlay network để máy chủ chỉ có một địa chỉ mà các thiết bị của bạn có thể route đến. Một control server Headscale tự host cung cấp mô hình này. Hoặc đặt một reverse proxy phía trước để xác thực request trước khi request đến port 3080, chẳng hạn một single sign-on server Authentik thực hiện forward auth. Reverse proxy không có auth đứng phía trước không phải là security control. Nó chỉ là một URL dài hơn.

Truy cập giao diện web qua SSH tunnel

Chạy lệnh này trên laptop của bạn, không phải trên server.

ssh -N -L 3080:127.0.0.1:3080 you@your-server

-L mở cổng 3080 trên laptop và chuyển tiếp mọi kết nối đến cổng đó qua phiên SSH đã mã hóa. Phần 127.0.0.1:3080 được phân giải trên server, nên kết nối đến harness từ loopback, giống hệt như khi bạn ngồi trực tiếp trên máy. -N yêu cầu không khởi động remote shell, vì bạn chỉ cần port forwarding.

Sau đó mở http://127.0.0.1:3080 bằng trình duyệt trên máy local. Nếu cổng 3080 đã được sử dụng trên laptop, hãy đổi số ở bên trái: ssh -N -L 3180:127.0.0.1:3080 you@your-server, rồi truy cập http://127.0.0.1:3180. Số bên trái là cổng local, còn số bên phải thuộc về server, nên chỉ thay đổi số bên trái.

Lưu vào ~/.ssh/config và không phải nhập lại.

Host dsh
  HostName 203.0.113.10
  User deploy
  IdentityFile ~/.ssh/id_ed25519
  LocalForward 3080 127.0.0.1:3080

Sau đó, ssh -N dsh sẽ khởi động tunnel. Nếu trình duyệt báo kết nối bị từ chối, nguyên nhân thường là tunnel đã hoạt động nhưng không có tiến trình nào đang listening ở đầu bên kia, vì SSH vẫn forward cổng bất kể harness có đang chạy hay không. Kiểm tra server bằng lệnh ss ở trên.

Duy trì harness chạy sau khi đăng xuất

Một lệnh npx sẽ dừng cùng shell của bạn. systemd user service vẫn chạy, đồng thời khởi động lại harness sau khi bị crash hoặc sau khi reboot.

loginctl enable-linger $USER
mkdir -p ~/.config/systemd/user
command -v dsh

enable-linger quan trọng vì user service thường dừng khi phiên cuối cùng của bạn kết thúc. Nếu thiếu thiết lập này, harness sẽ chết ngay khi bạn đóng tunnel. Lấy đường dẫn tuyệt đối do command -v dsh in ra và đặt đường dẫn đó vào unit, vì systemd không tìm trong PATH mà login shell của bạn tạo.

[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.target

WorkingDirectory không phải thiết lập cho có. Tiến trình dsh dùng thư mục gọi nó làm vị trí filesystem mặc định. Vì vậy, nếu service khởi động ở sai thư mục, agent sẽ nhận workspace mặc định không đúng. Bạn vẫn có thể chọn workspace trong UI.

systemctl --user daemon-reload
systemctl --user enable --now dsh
systemctl --user status dsh

Một unit không khởi động gần như luôn do đường dẫn ExecStart sai hoặc do binary không chấp nhận phiên bản Node hiện tại. journalctl --user -u dsh -n 50 cho biết nguyên nhân nào trong hai nguyên nhân này. Cùng mẫu cấu hình này cũng áp dụng cho duy trì bất kỳ coding agent nào chạy trên VPS, và các dạng lỗi là giống nhau.

Một plugin được phép làm gì

Plugin là một module cung cấp service, typed event và effect có thể hoàn tác cho một context dùng chung. Các extension point là phần cần đọc kỹ:

  • đăng ký model provider trên ctx.llm
  • thêm các tool dành cho model trên ctx.tools
  • cung cấp shell backend phía sau ctx.shell
  • cung cấp quyền truy cập filesystem hoặc policy phía sau ctx.fs
  • đăng ký human command trên ctx.commands
  • chạy tác vụ nền thông qua ctx.jobs
  • bọc các process được spawn bằng một backend ctx.sandbox
  • chặn request và tool call thông qua các event agent/*tools/*
  • mở rộng durable session state
  • điều khiển UI thông qua ctx.agents

Hãy đọc danh sách đó theo cách một attacker sẽ đọc. Plugin có thể cung cấp filesystem layer và shell layer, đồng thời đứng giữa mọi tool call do model thực hiện. Không có permission dialog nào ngăn plugin tiếp cận các điểm kết nối đó, vì plugin chỉ là mã Node thông thường được load vào cùng process với mọi thành phần khác. Cài một plugin đồng nghĩa với chạy mã của một bên không đáng tin bằng quyền của agent, mà quyền của agent chính là quyền của Unix user đang chạy agent.

Đây là cùng một quyết định về mức độ tin cậy như khi bạn gắn một MCP server vào agent trên VPS, trong đó MCP là model context protocol. Đây cũng là lý do chạy coding agent an toàn trên VPS phải bắt đầu từ account mà agent sử dụng, thay vì bắt đầu từ model, và là lý do các cuộc tấn công supply chain của npm gây hậu quả nghiêm trọng trên server: bước cài đặt chính là lúc hệ thống bị breached, và không có prompt nào xuất hiện.

Nguồn gốc của plugin

Plugin nằm trong các profile. Profile là một cấu hình kết hợp có tên, được lưu dưới $DSH_HOME. Theo mặc định, $DSH_HOME~/.dsh. Thư mục của mỗi profile chứa các plugin ngoài cây mã nguồn mà profile đó cài đặt. CLI quản lý chúng bằng cách chuyển thẳng các đối số của bạn đến pnpm, đồng thời dùng thư mục của profile làm thư mục làm việc.

dsh plugin --profile web add github:deepseek-harness/turtle-ui
dsh plugin --profile web remove turtle-ui

Vì các đối số được chuyển đến pnpm mà không thay đổi, add, remove, updatewhy hoạt động giống như trong mọi dự án pnpm. Plugin có thể là một npm package hoặc một tham chiếu GitHub. pnpm phải có sẵn trong PATH trước. Trên Node 22 trở lên, corepack enable pnpm sẽ thêm nó vào PATH.

Cơ chế discovery hoạt động thông qua một GitHub topic. Tác giả plugin thêm topic dsh-plugin vào repository của họ. Bạn tìm các plugin hiện có bằng cách duyệt topic đó. Topic là nhãn mà tác giả gắn cho repository của chính họ. Không ai review hoặc ký xác nhận topic này. Trang topic xếp hạng theo số sao, chỉ phản ánh mức độ phổ biến chứ không phản ánh độ an toàn.

Bốn thói quen giúp việc này dễ kiểm soát. Đọc source trước khi cài đặt, vì hầu hết plugin đủ nhỏ để đọc trong mười phút. Ghim chính xác version hoặc commit thay vì theo dõi một branch. Chạy harness bằng một user không sở hữu tài nguyên nào khác, trên một VPS mà bạn sẵn sàng cài lại. Cấp cho agent một API key riêng với spending limit riêng, tách khỏi key mà các service production sử dụng.

Nếu muốn so sánh các thiết kế trước khi chọn một phương án, harness multi-agent Omnigent giải quyết cùng vấn đề bằng một cấu trúc khác. Các đánh đổi sẽ trở nên rõ ràng khi plugin được đưa vào sử dụng.

Điều gì hỏng trước

Node quá cũ. Dự án yêu cầu Node 22.19 và các bản mới hơn trong nhánh 22.x, hoặc Node 24 trở lên; CI cũng kiểm thử trên các phiên bản đó. Runtime cũ sẽ lỗi ngay khi khởi động vì code sử dụng cú pháp và API không có trong phiên bản đó. Chạy node --version trước mọi thao tác khác.

Cổng 3080 đã bị chiếm. Có thể một harness khác, một tiến trình cũ hoặc một ứng dụng không liên quan cũng đang dùng cổng 3080. Tìm tiến trình đó bằng ss -tlnp | grep 3080, sau đó dừng nó hoặc khởi động harness trên cổng khác bằng dsh web --port 3180. --port thuộc về web app, nên phải đặt sau web.

Browser không thể kết nối qua tunnel. Xác nhận bạn đã truy cập 127.0.0.1, không phải địa chỉ public của server, vì cổng được forward chỉ tồn tại trên laptop của bạn. Sau đó xác nhận harness đang listen trên server, vì SSH vẫn thiết lập forward dù phía đích có tiến trình trả lời hay không.

dsh plugin lỗi ngay lập tức. Command này là wrapper của pnpm, nên nếu thiếu binary pnpm thì command sẽ dừng trước khi bắt đầu xử lý plugin.

Agent không nhìn thấy project của bạn. Workspace mặc định là directory nơi process được khởi động. Vì vậy, nếu WorkingDirectory của unit là home directory thì agent sẽ nhận home directory của bạn. Chọn workspace trong UI, hoặc sửa unit rồi reload.

FAQ

Có an toàn khi expose web UI của DeepSeek Harness trên cổng 3080 không?

Không. Web server không có cơ chế đăng nhập riêng, còn agent phía sau có thể chỉnh sửa file và chạy shell command bằng tài khoản đã khởi động process, trong khi provider API key của bạn được lưu trên cùng ổ đĩa. Hãy giữ listener trên 127.0.0.1 và truy cập nó qua SSH tunnel. Bạn cũng có thể dùng private overlay network hoặc reverse proxy xác thực mọi request trước khi chuyển đến cổng này. Từ version 0.1.0-rc.6, CLI từ chối --host 0.0.0.0 và thoát với usage error. Điều này cho thấy các tác giả đánh giá ý tưởng đó như thế nào.

Tôi có cần DeepSeek API key không, hay có thể dùng model local?

Cả hai đều được, vì harness là runtime chứ không phải model. Trong Settings, sau đó vào Models, bạn có thể dán key vào card của catalog provider hoặc chọn "Add a custom provider" rồi cung cấp base URL hỗ trợ giao thức tương thích với OpenAI. Ollama server local trả lời tại http://127.0.0.1:11434/v1/ và chấp nhận mọi chuỗi trong trường API key. Key được lưu tại $DSH_HOME/.credentials.yaml, mặc định là ~/.dsh/.credentials.yaml.

Việc cài plugin DeepSeek Harness thực sự cấp cho plugin những gì?

Plugin có các quyền của account đang chạy harness. Plugin là mã Node được load vào cùng process. Các extension point gồm shell backend, filesystem layer, tool registry và các event bao quanh mọi tool call. Không có cơ chế sandbox nào tách plugin khỏi các điểm tích hợp đó, trừ khi chính plugin cung cấp sandbox. Hãy đọc source trước khi cài đặt và chạy harness bằng một user không sở hữu dữ liệu nào quan trọng với bạn.

Nên cài version nào, và nó có tiếp tục hoạt động không?

Hãy cài một version cụ thể, chẳng hạn npx @deepseek-ai/dsh@0.1.0-rc.6 web. Đó là version mà tag latest trỏ tới vào ngày 13 August 2026. Project tự mô tả là bản developer preview và cho biết các thay đổi phá vỡ compatibility là điều có thể xảy ra. Vì vậy, command không pin version có thể hoạt động khác nhau giữa các ngày. Hãy kiểm tra repository trước khi upgrade và dự kiến config key cùng plugin interface có thể thay đổi trong khi version vẫn bắt đầu bằng 0.

#deepseek#agent-harness#tự lưu trữ#nodejs#plugins