云服务器部署Deepseek Harness:Nginx/Caddy反向代理与公网鉴权访问实战 1. 为什么要在云服务器上折腾 Deepseek Harness把 Deepseek Harness 跑在云服务器上这件事听起来像是把开发机搬到远端但真正动手之后你会发现它解决的其实是三个很现实的问题本地算力不够、团队协作不方便、以及随时随地的访问需求。我最早是在一台 16G 内存的笔记本上跑 Harness模型一加载风扇就开始起飞稍微跑点复杂任务就卡到怀疑人生。后来把整套东西迁到云服务器才算真正把能用变成了好用。Deepseek Harness 本质上是一个围绕大模型能力构建的工作台它把模型调用、插件扩展、Skill 编排、代码回退这些能力整合在一起让你可以像搭积木一样组合出适合自己的工作流。它本身不是一个模型而是一个调度中枢——你可以在里面接入不同的模型服务挂载各种插件然后通过对话或者任务的方式驱动它们干活。这一点很关键因为很多人第一次接触会误以为它是个聊天工具实际上它更像是一个可编程的 AI 工作环境。那为什么非要放到云服务器上我总结了几个绕不开的理由。第一是算力与内存Harness 本身加上模型服务、插件运行时内存占用很容易上到 8G 以上本地机器一边开 IDE 一边跑它体验会非常糟糕。第二是持续在线很多任务需要长时间运行本地机器一关机就断了云服务器可以 7x24 挂着。第三是公网访问你在外面用手机、用平板、用另一台电脑都能连回来继续干活这种体验一旦习惯就回不去了。但公网访问这四个字背后藏着一堆坑。直接把服务端口暴露到公网等于把家门钥匙插在门上不做鉴权任何人扫到你的 IP 就能进来翻你的数据。所以这篇内容的核心不只是怎么部署而是怎么安全地部署并让公网能访问。我会把 Nginx 和 Caddy 两条路线都讲清楚包括反向代理、鉴权、证书、以及那些文档里不会写的坑。适合读这篇的人有三类一是有云服务器但不知道怎么把 AI 工具跑起来的开发者二是想把 Harness 共享给团队用但不知道怎么加访问控制的人三是已经在本地跑通、想迁到公网但卡在反向代理和证书上的朋友。不管你是哪一类下面的内容都会从最基础的环境准备讲起一路讲到公网鉴权访问的完整链路。2. 云服务器选型与基础环境准备2.1 服务器配置怎么选才不踩坑选服务器这件事我的建议是内存优先CPU 够用就行。Harness 本身对 CPU 的要求不算高2 核就能跑起来但内存是硬指标。如果你打算在服务器上同时跑模型服务比如通过 Ollama 或者兼容接口接入那内存至少要 16G 起步32G 会更从容。如果只是把 Harness 当作调度层模型走外部 API那 8G 也能凑合但插件一多就容易吃紧。系统方面Ubuntu 22.04 或者 24.04 是目前最省心的选择社区资料多遇到问题好搜。CentOS 9 也能用但软件源配置和包管理会稍微麻烦一点新手不建议。磁盘我建议至少 40G因为模型缓存、日志、插件依赖加起来很容易占满尤其是你如果本地缓存模型权重那 100G 都不嫌多。带宽这块要单独说。很多人只关注服务器配置忽略了带宽。Harness 的 Web 界面本身流量不大但如果你要通过它传文件、拉模型、或者做流式输出带宽太小会非常难受。我一般建议至少 5Mbps 起步如果团队多人用10Mbps 以上更稳。提示买服务器之前先想清楚模型跑在哪。如果模型在服务器本地跑配置要拉满如果模型走外部 API服务器只需要承担调度和界面配置可以降一档。2.2 系统初始化与安全基线拿到服务器第一件事不是装软件而是做安全基线。我见过太多人上来就apt install结果 SSH 端口开着密码登录几天后就被扫爆了。正确的顺序是这样改 SSH 端口默认 22 端口是扫描重灾区改成 20000 以上的端口能过滤掉 90% 的自动化扫描。禁用密码登录改用密钥生成密钥对把公钥放到服务器然后关掉PasswordAuthentication。配置防火墙只放行 SSH 端口、HTTP80、HTTPS443其他一律拒绝。创建非 root 用户日常操作不要用 root创建一个普通用户并赋予 sudo 权限。这几步做完你的服务器才算有了基本的安全底座。后面部署 Harness 的时候服务本身也要遵循同样的思路——不暴露多余端口所有外部访问都经过反向代理。# 创建用户并赋予 sudo adduser harness usermod -aG sudo harness # 配置 SSH 密钥登录在本地执行 ssh-keygen -t ed25519 -C harness-server ssh-copy-id -p 22222 harnessyour-server-ip # 修改 SSH 配置 sudo vim /etc/ssh/sshd_config # 修改以下项 # Port 22222 # PasswordAuthentication no # PubkeyAuthentication yes sudo systemctl restart sshd防火墙用ufw就够了简单直接sudo ufw allow 22222/tcp sudo ufw allow 80/tcp sudo ufw allow 443/tcp sudo ufw enable sudo ufw status2.3 运行时依赖的安装顺序Harness 的运行依赖主要是 Node.js 运行时和包管理器。我推荐用nvm来管理 Node 版本因为不同插件对 Node 版本的要求可能不一样用 nvm 可以随时切换。Node 版本建议 20 LTS 以上18 也能跑但有些新插件会报错。# 安装 nvm curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash source ~/.bashrc # 安装 Node 20 nvm install 20 nvm use 20 nvm alias default 20 # 验证 node -v npm -v如果 Harness 的某些组件依赖 Python那还要装 Python 3.10 以上并且建议用venv隔离环境不要直接往系统 Python 里装包否则后面升级系统容易出问题。sudo apt install python3 python3-pip python3-venv -y python3 -m venv ~/harness-venv source ~/harness-venv/bin/activate安装顺序上我的经验是先系统依赖再运行时最后应用。系统依赖包括build-essential、git、curl、ca-certificates这些基础包很多编译型依赖没有它们会直接报错。这一步偷懒后面会加倍还回来。3. Deepseek Harness 的安装与本地验证3.1 安装方式的选择逻辑Harness 的安装方式主要有三种源码编译、包管理器安装、容器化部署。这三种没有绝对优劣关键看你的使用场景。源码编译适合想深度定制、跟进最新特性的人缺点是依赖管理麻烦升级要重新拉代码。包管理器安装最省事一条命令搞定但版本可能滞后。容器化部署隔离性最好环境干净迁移方便但调试稍微麻烦一点而且容器内的网络配置需要额外注意。我个人的选择是首次部署用容器化稳定运行后再考虑源码方式做定制。容器化能让你快速跑通全流程验证网络、鉴权、反向代理这些关键环节等整套链路稳定了再决定要不要深入改代码。如果你选择容器化Docker 和 Docker Compose 是必须的# 安装 Docker curl -fsSL https://get.docker.com | sudo sh sudo usermod -aG docker $USER newgrp docker # 验证 docker --version docker compose version3.2 首次启动与端口规划Harness 默认会监听一个本地端口通常是 3000 或者 8080 这类。这里有个关键原则应用只监听 127.0.0.1不监听 0.0.0.0。因为外部访问我们统一走反向代理应用本身不需要直接暴露。这样即使反向代理配置出问题服务也不会裸奔在公网上。端口规划我建议这样安排服务端口监听地址说明Harness 主服务3000127.0.0.1只允许本机访问模型服务可选11434127.0.0.1如果本地跑模型Nginx/Caddy80/4430.0.0.0对外唯一入口启动命令大概是这样docker run -d \ --name harness \ -p 127.0.0.1:3000:3000 \ -v ~/harness-data:/app/data \ --restart unless-stopped \ deepseek/harness:latest注意-p 127.0.0.1:3000:3000这个写法前面的127.0.0.1就是限制只监听本机。如果你写成-p 3000:3000那就等于监听所有网卡公网直接能访问这是很多安全事故的源头。3.3 本地验证的完整清单服务起来之后先别急着配反向代理在服务器本地验证一遍。这一步能帮你排除掉大部分问题避免后面把网络问题和应用问题混在一起排查。验证清单curl http://127.0.0.1:3000能返回页面或者 JSONdocker logs harness没有明显报错数据目录~/harness-data有文件写入如果接了模型服务curl http://127.0.0.1:11434/api/tags能列出模型我踩过的一个坑是容器里的服务默认监听0.0.0.0但我在启动参数里限制了127.0.0.1结果容器内部和宿主机的网络命名空间不一致导致curl不通。解决办法是确认容器的监听地址和端口映射一致必要时在容器内用netstat -tlnp看一下实际监听情况。注意本地验证通过之前绝对不要动反向代理配置。否则你会在应用没起来和代理配错了之间反复横跳浪费大量时间。4. 反向代理与公网访问的两条路线4.1 Nginx 路线的配置要点Nginx 是反向代理的老牌选手资料多、生态成熟缺点是配置相对繁琐证书续期要自己搞。如果你追求稳定和可控Nginx 是稳妥选择。核心配置其实就几行但每一行都有讲究server { listen 80; server_name harness.yourdomain.com; return 301 https://$host$request_uri; } server { listen 443 ssl http2; server_name harness.yourdomain.com; ssl_certificate /etc/letsencrypt/live/harness.yourdomain.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/harness.yourdomain.com/privkey.pem; location / { proxy_pass http://127.0.0.1:3000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection upgrade; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_read_timeout 300s; proxy_buffering off; } }这里有几个关键点必须解释清楚。Upgrade和Connection这两个头是给 WebSocket 用的Harness 的实时输出、流式响应都依赖 WebSocket不配这两个头界面会一直转圈。proxy_buffering off是给流式输出用的开着缓冲会导致输出一段一段蹦体验很差。proxy_read_timeout要调大因为模型推理可能很久默认 60 秒会直接断掉。证书用 Lets Encrypt 的 certbot 申请续期用 systemd timer 自动跑sudo apt install certbot python3-certbot-nginx -y sudo certbot --nginx -d harness.yourdomain.com sudo certbot renew --dry-run4.2 Caddy 路线的省心之处Caddy 最大的优势是自动 HTTPS你只要写个域名它自己去申请和续期证书完全不用管。对于不想折腾证书的人来说Caddy 是更优解。Caddyfile 配置简洁到令人感动harness.yourdomain.com { reverse_proxy 127.0.0.1:3000 { header_up Host {host} header_up X-Real-IP {remote_host} } }就这几行HTTPS、证书续期、HTTP/2 全部自动搞定。Caddy 会自动处理 WebSocket 升级不需要你手动配Upgrade头。这一点比 Nginx 省心太多。但 Caddy 也有它的坑。第一是端口占用Caddy 默认要占 80 和 443如果你服务器上已经有 Nginx 在跑会冲突。第二是日志排查Caddy 的日志格式和 Nginx 不一样习惯 Nginx 的人一开始会不适应。第三是插件生态Nginx 有大量第三方模块Caddy 相对少一些如果你有特殊需求比如复杂的限流、WAFNginx 更灵活。安装 Caddy 很简单sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl -1sLf https://dl.cloudsmith.io/public/caddy/stable/gpg.key | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg curl -1sLf https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt | sudo tee /etc/apt/sources.list.d/caddy-stable.list sudo apt update sudo apt install caddy4.3 Nginx 与 Caddy 的选型对照到底选哪个我整理了一张对照表按你的实际情况对号入座维度NginxCaddy证书管理手动配置 certbot全自动配置复杂度中等偏高低WebSocket需手动配头自动处理性能极高高生态与模块丰富一般排查难度资料多好搜资料相对少适合人群有运维经验想快速上线我的建议是如果你只是想快速把 Harness 暴露到公网并且有 HTTPS选 Caddy如果你后续还要在这台服务器上跑一堆服务需要精细控制选 Nginx。两者不冲突但同一台机器上不要同时监听 80/443。5. 公网鉴权访问的落地细节5.1 为什么不能只靠隐藏路径很多人觉得我把路径设复杂一点别人猜不到就行了这是典型的安全错觉。公网扫描器会遍历常见路径而且你的域名一旦解析就进入了被扫描的范围。隐藏路径只能算降低被发现的概率不能算鉴权。真正的鉴权要在反向代理层做让未授权的请求在到达 Harness 之前就被拦下来。这样即使 Harness 本身有漏洞攻击面也小很多。5.2 Basic Auth 的快速落地最简单的鉴权是 HTTP Basic AuthNginx 和 Caddy 都支持。虽然它安全性一般密码是 base64 编码传输靠 HTTPS 保护但对于个人使用或者小团队来说够用了。Nginx 配置sudo apt install apache2-utils -y sudo htpasswd -c /etc/nginx/.htpasswd youruser然后在 server 块里加location / { auth_basic Restricted; auth_basic_user_file /etc/nginx/.htpasswd; proxy_pass http://127.0.0.1:3000; # ... 其他代理配置 }Caddy 配置更简单harness.yourdomain.com { basicauth { youruser $2a$14$... # 用 caddy hash-password 生成 } reverse_proxy 127.0.0.1:3000 }生成密码哈希caddy hash-password --plaintext yourpassword5.3 更稳妥的方案接入统一身份认证Basic Auth 的问题是密码管理麻烦多人使用时不好做权限区分。如果你有更高要求可以考虑接入 OAuth2 代理比如oauth2-proxy它可以对接各种身份提供商实现单点登录。这个方案稍微复杂一点但好处很明显不用手动管理密码可以精细控制谁能访问还能记录访问日志。对于团队使用场景这是更专业的选择。部署oauth2-proxy的大致流程是先在你的身份提供商那边注册一个应用拿到 client id 和 secret然后启动 oauth2-proxy 指向 Harness最后在 Nginx 里把鉴权转发给它。具体配置因提供商而异这里不展开但思路是通用的。提示无论用哪种鉴权方式HTTPS 都是前提。没有 HTTPSBasic Auth 的密码等于明文传输OAuth2 的 token 也可能被截获。5.4 鉴权配置的常见坑第一个坑是鉴权范围。如果你把auth_basic加在location /上那所有请求都要鉴权包括静态资源。这本身没问题但如果你有健康检查接口记得给它开白名单否则监控会一直报 401。第二个坑是WebSocket 与鉴权。有些鉴权方案对 WebSocket 支持不好导致界面能打开但实时功能失效。Basic Auth 一般没问题OAuth2 要注意配置 WebSocket 的 token 传递方式。第三个坑是缓存。浏览器可能会缓存 Basic Auth 的凭据导致你改了密码之后旧密码还能用。测试的时候记得用无痕模式或者清缓存。6. 部署后的稳定性与排错经验6.1 日志体系的搭建服务跑起来只是开始能不能稳定运行关键看日志。我建议至少配置三层日志反向代理日志、Harness 应用日志、系统日志。Nginx 的访问日志和错误日志默认在/var/log/nginx/Caddy 的日志可以用journalctl -u caddy看。Harness 的日志通过docker logs或者挂载的日志目录查看。系统层面用journalctl看服务状态。排查问题时顺序是从外到内先看反向代理有没有收到请求再看请求有没有转发到 Harness最后看 Harness 有没有正常处理。这样能快速定位问题出在哪一层。6.2 几个高频故障的排查链路故障一502 Bad Gateway。这个最常见说明反向代理连不上后端。排查步骤先curl 127.0.0.1:3000确认 Harness 活着再检查 Nginx 配置里的proxy_pass地址对不对最后看防火墙有没有拦住本地回环。故障二界面能开但功能不响应。大概率是 WebSocket 没配好。检查 Nginx 的Upgrade和Connection头或者换 Caddy 试试。用浏览器开发者工具的 Network 面板看 WS 连接是不是 101 状态。故障三证书报错。常见的是net::ERR_CERT_COMMON_NAME_INVALID说明证书域名和访问域名不匹配。检查证书申请时的域名和实际访问的域名是否一致有没有漏掉www或者子域名。故障四流式输出卡顿。检查proxy_buffering是不是开着proxy_read_timeout是不是太短。这两个参数对流式体验影响很大。6.3 资源监控与自动重启服务器跑久了内存泄漏、进程卡死都可能发生。我建议配置一个简单的监控和自动重启机制。用systemd管理服务的话可以配置Restartalways进程挂了自动拉起。用 Docker 的话--restart unless-stopped就够了。再配合一个定时任务检查服务健康状态异常时发通知。# 简单的健康检查脚本 #!/bin/bash if ! curl -sf http://127.0.0.1:3000/health /dev/null; then echo Harness is down, restarting... docker restart harness fi放到 crontab 里每分钟跑一次能覆盖大部分意外情况。6.4 数据备份与迁移Harness 的数据主要在挂载目录里包括配置、插件、会话记录等。定期备份这个目录迁移的时候直接打包带走换台服务器解压就能恢复。# 备份 tar -czf harness-backup-$(date %Y%m%d).tar.gz ~/harness-data # 恢复 tar -xzf harness-backup-20240101.tar.gz -C ~/备份频率看你的使用强度个人用每周一次够了团队用建议每天一次并且保留最近 7 天的版本。7. 插件与 Skill 的部署实践7.1 插件安装的路径与权限Harness 的插件机制是它的核心价值之一但插件安装经常遇到权限问题。尤其是在 Linux 上如果 Harness 以某个用户身份运行插件目录的属主必须匹配否则会报setnamedsecurityinfow failed这类错误。解决办法是确认运行用户和目录属主一致# 查看 Harness 运行用户 docker inspect harness | grep -i user # 修改目录属主 sudo chown -R 1000:1000 ~/harness-data/plugins如果你用的是非容器方式直接chown成当前用户即可。关键是不要让插件目录的权限和运行用户错位。7.2 Skill 的编排与调试Skill 是 Harness 里比较高级的能力它允许你把多个步骤编排成一个可复用的工作流。部署 Skill 的时候最容易出问题的是文件路径和环境变量。Skill 里引用的文件路径如果是相对路径基准目录是 Harness 的工作目录不是 Skill 文件所在目录。这一点很容易搞混。建议统一用绝对路径或者在 Skill 配置里显式声明工作目录。环境变量方面Skill 运行时继承的是 Harness 进程的环境变量。如果你在 Skill 里调用了某个命令行工具而这个工具依赖特定的环境变量记得在启动 Harness 的时候就把它注入进去而不是在 Skill 里临时设置。7.3 离线环境下的插件部署有些场景下服务器不能访问外网插件没法在线安装。这时候需要提前在有网的机器上下载好插件包再传到服务器手动安装。流程是在有网机器上找到插件的发布包通常是.tar.gz或者.zip下载后传到服务器解压到插件目录然后重启 Harness。注意检查插件的依赖有些插件会依赖特定的运行时库离线环境下要一并准备好。注意离线部署时插件的版本要和 Harness 的版本匹配。版本不匹配可能导致插件加载失败甚至让 Harness 启动不了。装之前先看插件的兼容性说明。8. 我在这套流程里踩过的几个真实坑第一个坑是端口监听的误解。我一开始以为-p 3000:3000和-p 127.0.0.1:3000:3000没区别结果前者让服务直接暴露在公网被扫描器盯上日志里一堆异常请求。后来改成后者配合防火墙才清净下来。这个教训是默认不信任任何网络能限制就限制。第二个坑是证书续期失败。用 certbot 申请证书后我忘了配置自动续期三个月后证书过期网站直接打不开。后来加了 systemd timer并且设置了续期前通知才没再出问题。如果你用 Caddy这个问题不存在它会自动续期。第三个坑是WebSocket 超时。Harness 的实时输出依赖 WebSocket但 Nginx 默认的proxy_read_timeout是 60 秒长任务跑到一半就断了。改成 300 秒后正常但更稳妥的做法是配置 WebSocket 的心跳让连接保持活跃。第四个坑是插件权限。装了一个文件操作相关的插件一直报权限错误查了半天才发现是容器内用户和挂载目录属主不一致。改成一致的 UID 后解决。这个问题的隐蔽性在于错误信息指向的是插件本身而不是权限配置。第五个坑是内存溢出。服务器配置是 8G跑了一段时间后 Harness 被 OOM Killer 干掉。查日志发现是某个插件缓存了大量数据没释放。解决办法是限制插件的内存使用或者升级服务器配置。这也印证了前面说的内存优先。9. 关于公网访问的一些个人体会把 AI 工具放到公网便利性和风险是并存的。我的原则是能内网就内网必须公网就加鉴权鉴权之外再加一层网络层的限制。比如你可以只允许特定 IP 段访问或者用零信任方案做设备认证。这些措施叠加起来安全性会高很多。另外公网访问不代表要把所有功能都开放。Harness 里有些高危操作比如执行系统命令、读写任意文件这些功能最好限制在本地或者内网使用。公网入口只开放必要的界面和 API把攻击面压到最小。最后说个实际的如果你只是自己用其实不一定非要公网。用 SSH 端口转发把服务器的端口映射到本地一样能访问而且安全性高得多。公网访问更适合团队协作或者需要随时随地接入的场景。想清楚自己的真实需求再决定要不要走公网这条路能省掉很多不必要的麻烦。