2G2核服务器部署deep seekharness 困难?资源不够?DeepSeek Harness 部署复用笔记

DeepSeek Harness 部署复用笔记

适用场景:已有一台阿里云 Ubuntu 服务器,服务器上已有一个工具网站;希望额外部署 DeepSeek Harness,并通过公网 IP + Nginx 登录验证访问。

注意:不要把真实 API Key 写进文档、截图或聊天里。

1. 最终架构

最终采用的是:

复制代码
浏览器访问 http://服务器公网IP:4081
        ↓
Nginx Basic Auth 登录验证
        ↓
Nginx 反向代理到 127.0.0.1:3080
        ↓
DeepSeek Harness Web 服务
        ↓
DeepSeek API

端口关系:

复制代码
4081:公网入口,Nginx 监听
3080:服务器内部端口,Harness 本体监听
80:原小陈工具网站入口
3000:小陈工具网站后端内部端口

核心 Nginx 配置关系:

复制代码
listen 4081;
proxy_pass http://127.0.0.1:3080;

简单记:

复制代码
外面进 4081,里面转 3080。

2. 这次遇到的主要问题

2.1 原服务器配置偏低

原服务器大概是:

复制代码
Ubuntu 24.04
2 核 2 GiB
已有小陈工具网站运行

直接在这台服务器源码构建 Harness 时,pnpm installpnpm run build 会吃大量内存和 CPU,导致:

复制代码
CPU 100%
内存 90%+
swap 接近用满
SSH 卡顿
原网站短暂打不开

结论:

复制代码
2核2G 可以尝试运行,但不适合源码构建大型项目。

2.2 GitHub clone 不稳定

服务器 git clone 出现过:

复制代码
GnuTLS recv error (-110)

说明服务器访问 GitHub HTTPS 不稳定。后来采用:

复制代码
本地下载源码 ZIP
本地/虚拟机编译
打包上传服务器

2.3 URL 复制成 Markdown 格式

错误形式:

复制代码
[https://example.com](https://example.com)

命令行里应该只输入纯 URL:

复制代码
https://example.com

否则可能导致:

复制代码
下载到 9 字节错误文件
Git 要求输入 Username/Password
curl 访问错误地址

2.4 pnpm 下载慢或卡住

项目使用 pnpm,不是普通 npm 项目。因为仓库里有:

复制代码
pnpm-lock.yaml
pnpm-workspace.yaml

说明这是 pnpm workspace/monorepo。

常用优化:

复制代码
pnpm config set registry https://registry.npmmirror.com
pnpm config set fetch-timeout 180000
pnpm config set fetch-retries 5
pnpm config set network-concurrency 1
pnpm install --network-concurrency 1

2.5 构建时报 git rev-parse HEAD

如果源码是 ZIP 解压,不是 git clone,构建脚本可能报:

复制代码
Error: Command failed: git rev-parse HEAD

解决:在源码目录临时初始化 Git:

复制代码
git init
git config user.email "local@local"
git config user.name "local"
git add .
git commit -m "local build"

2.6 构建时报缺 cc

报错:

复制代码
spawnSync cc
ENOENT

意思是缺 C 编译器。

解决:

复制代码
sudo apt update
sudo apt install -y build-essential python3 make g++ pkg-config

2.7 构建时报内存不足

报错:

复制代码
JavaScript heap out of memory

说明 Node 编译时堆内存不足。

项目里有构建参数:

复制代码
--max-old-space-size=4096

意思是允许 Node 最多用 4GB JS 堆内存。

如果服务器只有 2G 内存,即使有 2G swap,也很吃紧。可以临时加大 swap,但更推荐本地虚拟机构建。

2.8 systemd 启动出现端口占用

日志:

复制代码
EADDRINUSE: address already in use 127.0.0.1:3080

原因:之前手动启动过 Harness,占着 3080,后来 systemd 又启动一个 Harness,也想占 3080

解决:只保留 systemd 管理的服务。

复制代码
systemctl stop deepseek-harness
ss -lntp | grep ':3080'
kill -9 PID
systemctl start deepseek-harness

3. 本地 VMware Ubuntu 构建流程

因为 Windows 没有 WSL,Docker Desktop 又要求 WSL,所以改用 VMware Ubuntu。

Ubuntu 虚拟机建议:

复制代码
Ubuntu 24.04 Desktop
内存 6G 或 8G
CPU 4 核
硬盘 50G
网络 NAT

安装后打开终端:

复制代码
sudo apt update
sudo apt install -y curl git unzip tar openssh-client build-essential python3 make g++ pkg-config

安装 Node 22:

复制代码
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo bash -
sudo apt install -y nodejs
node -v
npm -v

安装 pnpm:

复制代码
sudo npm install -g pnpm
pnpm -v

下载 Harness:

复制代码
cd ~
git clone https://github.com/deepseek-ai/deepseek-harness.git
cd deepseek-harness

如果是 ZIP 解压,需要补 Git 信息:

复制代码
git init
git config user.email "local@local"
git config user.name "local"
git add .
git commit -m "local build"

安装依赖并构建:

复制代码
pnpm config set registry https://registry.npmmirror.com
pnpm install
pnpm run build

构建成功后打包:

复制代码
cd ~
tar -czf deepseek-harness-built.tar.gz deepseek-harness

注意:tar 命令里输出文件名和目录之间必须有空格。

正确:

复制代码
tar -czf deepseek-harness-built.tar.gz deepseek-harness

错误:

复制代码
tar -czf deepseek-harness-built.tar.gz.deepseek-harness

上传服务器:

复制代码
scp ~/deepseek-harness-built.tar.gz root@服务器公网IP:/srv/

4. 服务器解压和运行

服务器上解压:

复制代码
cd /srv
rm -rf /srv/deepseek-harness-built
mkdir -p /srv/deepseek-harness-built
tar -xzf /srv/deepseek-harness-built.tar.gz -C /srv/deepseek-harness-built --strip-components=1
cd /srv/deepseek-harness-built
ls package.json
ls node_modules

临时启动测试:

复制代码
cd /srv/deepseek-harness-built
DEEPSEEK_API_KEY='你的真实Key' DSH_TRUSTED_HOSTS='服务器公网IP:4081,127.0.0.1:3080,127.0.0.1:4081' pnpm dsh web --host 127.0.0.1 --port 3080 --no-open

确认端口:

复制代码
ss -lntp | grep -E ':3080|:4081'

应该看到:

复制代码
127.0.0.1:3080 node
0.0.0.0:4081 nginx

5. Nginx 配置

文件位置:

复制代码
/etc/nginx/sites-available/harness

推荐配置:

复制代码
server {
    listen 4081;
    server_name 47.*.*.*;

    auth_basic "DeepSeek Harness";
    auth_basic_user_file /etc/nginx/.harness_passwd;

    location / {
        proxy_pass http://127.0.0.1:3080;
        proxy_http_version 1.1;

        proxy_set_header Host 127.0.0.1:3080;
        proxy_set_header Origin http://127.0.0.1:3080;
        proxy_set_header X-Forwarded-Host $http_host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

        proxy_read_timeout 3600;
        proxy_send_timeout 3600;
        proxy_buffering off;
    }
}

重要备注:

复制代码
proxy_set_header Host 127.0.0.1:3080;

proxy_set_header Host 127.0.0.1:3080; 表示 Nginx 转发请求给 DeepSeek Harness 后端服务时,把 HTTP 请求头里的 Host 设置为 127.0.0.1:3080。DeepSeek Harness 后端服务实际监听地址是 127.0.0.1:3080,所以 DeepSeek Harness 后端服务会把这次请求识别成本机访问。

proxy_set_header Host http://127.0.0.1:3080; 是错误写法。Host 请求头不能包含 http://。Host 请求头只能包含主机名和端口,例如 127.0.0.1:3080

复制代码
proxy_set_header Origin http://127.0.0.1:3080;

proxy_set_header Origin http://127.0.0.1:3080; 表示 Nginx 转发请求给 DeepSeek Harness 后端服务时,把浏览器来源 Origin 设置为 http://127.0.0.1:3080。Origin 请求头可以包含 http://

如果浏览器打开"选择工作区目录"时出现 client api: directoryPicker/list failed: transport failure for /api/directoryPicker/list: HTTP 403,优先检查 Nginx 配置文件中是否错误写成了 proxy_set_header Host http://127.0.0.1:3080;。正确写法必须是 proxy_set_header Host 127.0.0.1:3080;

创建网页登录密码:

复制代码
htpasswd -c /etc/nginx/.harness_passwd admin

启用配置:

复制代码
ln -s /etc/nginx/sites-available/harness /etc/nginx/sites-enabled/harness
nginx -t
systemctl reload nginx

访问:

复制代码
http://服务器公网IP:4081

6. systemd 后台服务

服务文件位置:

复制代码
/etc/systemd/system/deepseek-harness.service

示例:

复制代码
[Unit]
Description=DeepSeek Harness Web
After=network.target

[Service]
Type=simple
WorkingDirectory=/srv/deepseek-harness-built
Environment="DEEPSEEK_API_KEY=你的真实Key"
Environment="DSH_TRUSTED_HOSTS=服务器公网IP:4081,127.0.0.1:3080,127.0.0.1:4081"
ExecStart=/usr/bin/pnpm dsh web --host 127.0.0.1 --port 3080 --no-open
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target

启用:

复制代码
systemctl daemon-reload
systemctl enable deepseek-harness
systemctl start deepseek-harness

常用管理命令:

复制代码
systemctl status deepseek-harness --no-pager
systemctl restart deepseek-harness
systemctl stop deepseek-harness
journalctl -u deepseek-harness -n 100 --no-pager

7. Token 怎么找

Harness 自己有一层 token 认证。服务重启后 token 可能变化。

找日志中的 URL:

复制代码
journalctl -u deepseek-harness -n 300 --no-pager -o cat | grep -Eo 'http://[^ ]+'

只看最新一个:

复制代码
journalctl -u deepseek-harness -n 300 --no-pager -o cat | grep -Eo 'http://[^ ]+' | tail -1

直接转换成公网访问 URL:

复制代码
journalctl -u deepseek-harness -n 300 --no-pager -o cat | grep -Eo 'http://127.0.0.1:3080/[^ ]+' | tail -1 | sed 's#http://127.0.0.1:3080#http://服务器公网IP:4081#'

如果没有输出,可能是服务没正常启动,先看:

复制代码
systemctl status deepseek-harness --no-pager
journalctl -u deepseek-harness -n 120 --no-pager

8. API Key 验证

不要把真实 Key 发到聊天里。

服务器上测试 Key:

复制代码
curl https://api.deepseek.com/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer 你的Key" \
  -d '{"model":"deepseek-chat","messages":[{"role":"user","content":"hello"}],"stream":false}'

常见结果:

复制代码
Authentication Fails / invalid api key:Key 无效
Insufficient Balance:Key 有效,但余额不足
返回 assistant 内容:调用成功

如果 deepseek-chat 余额不足,但 deepseek-flash 成功,说明:

复制代码
Key 有效,但当前模型、余额或权限不同。

10. 复用 FAQ

Q1:为什么不用 npm,要用 pnpm?

因为 DeepSeek Harness 仓库里有:

复制代码
pnpm-lock.yaml
pnpm-workspace.yaml

说明它是 pnpm workspace 项目。用 npm 可能导致 workspace 包链接不对、依赖版本不一致、构建失败。

Q2:listen 4081proxy_pass 是在哪运行?

它们不是命令,是 Nginx 配置,写在:

复制代码
/etc/nginx/sites-available/harness

修改后执行:

复制代码
nginx -t
systemctl reload nginx

Q3:为什么访问会弹用户名密码?

这是 Nginx Basic Auth,配置来自:

复制代码
auth_basic "DeepSeek Harness";
auth_basic_user_file /etc/nginx/.harness_passwd;

用户名通常是:

复制代码
admin

忘记密码可重设:

复制代码
htpasswd -c /etc/nginx/.harness_passwd admin
systemctl reload nginx

Q4:为什么浏览器显示 dsh web authentication required

这是 Harness 自己的 token 认证。需要用 dsh web 启动时打印的 token URL。

公网访问时,把:

复制代码
http://127.0.0.1:3080/?token=xxx

改成:

复制代码
http://服务器公网IP:4081/?token=xxx

Q5:为什么页面一直"自动重连中"?

常见原因:

复制代码
Harness 后端挂了
Nginx WebSocket/长连接转发不完整
3080 端口冲突
服务反复重启

检查:

复制代码
ss -lntp | grep -E ':3080|:4081'
journalctl -u deepseek-harness -n 120 --no-pager
tail -n 80 /var/log/nginx/error.log

Q6:EADDRINUSE 127.0.0.1:3080 是什么?

端口被占用。通常是手动启动的 Harness 没停,systemd 又启动了一个。

处理:

复制代码
systemctl stop deepseek-harness
ss -lntp | grep ':3080'
kill -9 PID
systemctl start deepseek-harness

Q7:API 密钥无效 一定是 Key 错吗?

不一定。可能是:

复制代码
Key 真无效
余额不足
模型名不对
模型没权限
systemd 没读到新 Key

最准确是用 curl 直接测 DeepSeek API。

Q8:Insufficient Balance 是什么?

Key 有效,但账户余额不足。充值或换可用模型。

Q9:Ubuntu ISO 安装完要删吗?

可以删。VMware 虚拟机装好后,ISO 只是一张"安装光盘镜像",不再需要。删除可释放约 5-6GB 空间。

Q10:.service 文件是什么?

是 systemd 的服务说明书,不是业务代码。真正执行的是里面的:

复制代码
ExecStart=...

例如:

复制代码
systemctl start deepseek-harness

就是让 systemd 按 /etc/systemd/system/deepseek-harness.service 的说明启动 Harness。

相关推荐
赵民勇1 小时前
systemd-sysusers命令详解
linux·运维
huainingning1 小时前
盈高安全准入设备与深信服实现单点登录对接配置
服务器·网络·安全
本人手速666+1 小时前
企业微信 API 接入层如何降低业务系统复杂度
运维·网络协议·微信·自动化·ipad
小年糕是糕手1 小时前
【AI】中国 AI:从跟随,到并肩
ai·chatgpt·agent·codex·deepseek
Anthony_2311 小时前
Nginx基础
服务器·nginx·http·https·edge浏览器·web
秦jh_2 小时前
【Docker】容器
运维·docker·容器
刘婉晴2 小时前
【K8S】配置和连接介绍
运维
是枚小菜鸡儿吖2 小时前
Windows 和 iPhone 怎么互传文件?用 PairDrop 搭一个自己的浏览器传输入口
服务器·人工智能·大模型
网硕互联的小客服2 小时前
如何在Ubuntu系统上查看和刷新DNS缓存?操作方法与原理解析
运维·服务器·网络·ubuntu