如果你也到了需要把本地的大模型推理服务搬到公网的阶段,这篇东西应该能帮你少熬几个夜。事情起因是内部工具要跑一个基于 Deepseek 的 Harness 推理服务,让不在同一办公地点的同事也能通过公网安全访问。真做下来才发现,云服务器部署 Deepseek Harness 全流程本身不复杂,真正磨人的是公网鉴权访问这层安全网——既要让外网用起来顺畅,又要挡住扫描、滥用和误操作。
这篇文章会把完整流程拆开讲:服务器怎么选、模型权重怎么准备、Harness 服务怎么起、公网 HTTPS 和鉴权怎么配、内网调试到公网放行的顺序是什么,最后是我踩过的一些坑和稳定运行后的配置参考。适合有一定 Linux 基础、打算把私有 Deepseek 服务开放给团队使用的开发者。如果只是本机跑 demo,公网部分可以跳过,但部署和验证思路同样值得参考。
1. 为什么要把 Deepseek Harness 放到公网:需求背景与整体架构
1.1 三个绕不开的现实问题
我这次部署的起因很朴素:某个内部工具需要稳定的文本推理能力,但数据不能全部走外部大模型 API,刚好 Deepseek 有可本地部署的开源权重,于是决定自建。最初的想法特别简单:内网跑起来就行。可实际情况是团队不在同一个办公区,有人在外地、有人在家,服务如果只绑在办公网内,这些人就全被挡在门外。于是需求从“本地能跑”变成了“公网能安全访问”。
第二个问题是多人共用。一旦多个人同时请求,没有统一入口的话,每个人各连底层模型端口,显存很快会被打满,而且一点可观测性都没有。Harness 这层实际上承担了请求排队、会话区分和调用统计,相当于给模型加了一个调度前台。没有这层封装,后面做鉴权也根本没地方挂。
第三个问题是安全。公网意味着任何人都可能扫到你的服务器 IP,模型服务如果裸露在公网,轻则被刷爆资源,重则被当成免费 AI 接口滥用。所以公网放行不是简单开个端口,必须配一整套鉴权、限流和访问控制方案。
1.2 整体架构一句话讲清楚
整个链路可以抽象成三层:最外层是 HTTPS 入口,中间是鉴权网关,最里面是 Harness 推理服务。
客户端请求先经过域名解析落到云服务器公网 IP,Nginx 在 443 端口接收请求,校验 HTTPS 证书、API Key、限流条件,确认没问题后再转发给回环地址上的 Harness 服务。Harness 内部再调度 Deepseek 模型完成推理,把结果沿原路返回。
这里面最容易忽略的一点是:后端服务监听地址一定用回环地址 127.0.0.1,而不是 0.0.0.0。原因不复杂:让 Nginx 成为唯一对外的门,其余服务不暴露在公网,自然少挨打。我们用了一段时间后发现,这个小小的绑定习惯,比任何复杂的防火墙规则都重要。
1.3 为什么选 Nginx 做门面
市面上能当反向代理的组件不少,有些新工具配置更简洁,容器环境下也有更适合的选择。但我在这个项目里还是选了 Nginx,原因是它足够稳。长连接和并发处理在裸机部署下性能损耗很小,配置语法透明,限流、鉴权、请求体限制都是几行配置的事,排查问题时能很清楚地确认每一层发生了什么。
还有一个现实因素:团队其他人更熟悉 Nginx,后续维护和交接成本低。技术选型经常不是比谁最强大,而是比谁最容易长期维护。对于中小规模的自建推理服务,Nginx 是最不出幺蛾子的选择。
2. 服务器初始化:选型、系统配置与安全基线
2.1 服务器配置怎么定
选择云服务器时,最关键的其实是显存。Deepseek 有不同规格的权重,如果业务是普通文本生成、并发不高,单卡 24GB 级别的显存基本够用。想跑更大参数版本或者更长上下文,显存就要往上加,服务器内存也不能太小,建议至少 64GB 起步。推理框架加载权重时经常先把参数读进内存再搬运到显存,内存不足会出现进程被系统直接杀死的情况。
磁盘是另一个容易被低估的项。权重文件动辄几十 GB,加上日志和快照需求,建议系统盘和数据盘分开,数据盘单独挂载到 /data 这类目录下,系统重装也不会丢权重。
带宽按实际并发来定。普通团队 5M 到 10M 就够用,公网访问下真正吃带宽的是上传下载长文本请求,频率不高就不会成为瓶颈。
2.2 系统初始化命令参考
我用的系统是 Ubuntu 22.04 LTS。新机器到手后,第一件事不是装模型服务,而是把账号体系和防火墙理清楚。直接拿 root 跑服务不是不行,但一旦服务被利用,权限过大很难收拾。
# 创建普通用户并加入 sudo 组 adduser deployer usermod -aG sudo deployer # 把本机公钥写入 authorized_keys mkdir -p /home/deployer/.ssh echo "ssh-rsa ..." >> /home/deployer/.ssh/authorized_keys chown -R deployer:deployer /home/deployer/.ssh chmod 700 /home/deployer/.ssh chmod 600 /home/deployer/.ssh/authorized_keys然后是防火墙。云厂商控制台的安全组和服务器内的 ufw 要同时检查,两层都放行才算数。
ufw allow OpenSSH ufw allow 80/tcp ufw allow 443/tcp ufw enable ufw status verbose这里要特别提个醒:部署阶段不要图省事把 Harness 端口直接放进防火墙。后端服务先跑回环地址,Nginx 配好之前,业务端口不需要对外。很多事故就是安全组忘了改,ufw 又开着测试端口,导致服务提前暴露。
2.3 依赖环境:CUDA 与运行方式选择
这次部署是在裸机上直接跑的,没有用容器。理由不是容器不好,而是团队需要直接看推理进程的资源占用,裸机排查显存问题更直观。如果你更看重环境隔离和分钟级回滚,容器方案会更合适,但思路是一样的。
装推理环境前,先确认 CUDA 驱动。建议用 nvidia-smi 查看驱动版本,再按对应版本装 CUDA 运行时,不要凭感觉装最新版。驱动和 CUDA 不匹配是部署阶段最常见的隐形坑,报错方式千奇百怪,比如加载权重时提示显存初始化失败、内核模块版本不对等,排查起来很费时间。
3. Harness 与模型加载:权重准备、启动参数与首次自检
3.1 权重准备不是下载解压那么简单
第一次拉权重时,我犯过一个低级错误:没提前估算磁盘占用,下载到一半系统盘满了。建议先规划目录结构,把权重放到独立数据盘,放好后核对文件数量和校验值。下载过程如果中断,最好用支持断点续传的工具重新拉,不要拿残缺文件强行加载,否则模型加载阶段会出现各种奇怪的错误。
权重目录权限同样要注意。Harness 进程以 deployer 用户运行时,权重目录至少要让该用户可读,避免出现 root 下载、普通用户读不了的权限错位问题。检查命令很简单:
ls -lh /data/models/确认权重文件权限可读,再继续下一步。
3.2 Harness 启动参数里值得盯的几个值
不同团队可能用不同 Harness 实现,我这里基于自建的一套配置给你参考。它的作用是把 Deepseek 模型封装成统一入口,对外暴露 OpenAI 兼容的接口格式,对内做并发控制和调用统计。启动参数我重点关注这几项:
| 参数 | 我的取值 | 说明 |
|---|---|---|
| 监听地址 | 127.0.0.1 | 只允许本机访问,公网全部走到 Nginx |
| 监听端口 | 8000 | 内部端口,不与常见 Web 端口冲突 |
| 默认并发 | 4 | 受显存限制,宁小勿大 |
| 单请求超时 | 120s | 长文本生成场景必须放宽 |
| 请求体上限 | 64MB | 避免超大 prompt 拖垮服务 |
首次启动建议用前台模式跑,日志直接打到终端,确认模型加载完成后按 Ctrl+C 再改用 systemd 托管。前台模式下能清楚看到每个阶段的耗时:模型映射、显存分配、预热,整个环节正常的话,启动日志是顺滑的,不会出现反复重试的警告。
3.3 用 curl 做第一次自检
服务启动后,先不要碰任何鉴权,直接用本机 curl 打一次接口。打通了后面加安全层才有意义。
curl -X POST http://127.0.0.1:8000/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{"model": "deepseek-chat", "messages": [{"role": "user", "content": "你好"}], "stream": false}'返回正常 JSON 说明推理链路没问题。这一步切记在本机完成,不要绕到公网 IP 去测。本机通了,才有必要包装网关;本机都不通,后面所有排查都会被网络层干扰。
4. 公网访问的鉴权设计:Nginx 网关、API Key 与限流
4.1 HTTPS 是公网鉴权的地基
公网访问的第一个前提是加密。裸 HTTP 下即使带了 API Key,也会在链路中被抓包暴露。所以必须先上 HTTPS。我用的是免费证书签发工具自动申请证书,域名解析配置好后,一条命令就能签发,再配一个自动续期任务,证书过期问题基本不用管。
申请证书的前提是域名已经解析到云服务器 IP,并且 80 端口能临时访问用于验证。签发完成后,证书文件路径要记清楚,后续 Nginx 配置里要用到。常见路径是 /etc/ssl/certs 和 /etc/ssl/private,按自己的工具默认路径来也可以。
4.2 Nginx 配置:把鉴权做在请求进门之前
我在 Nginx 里做了三层防护:HTTPS 终结、API Key 校验、限流。下面配置是一位同事后来评价"这配置一看就不想动"的那个版本,简单直接,够用。
# 限流:按 IP 限制,防止暴力刷接口 limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s; limit_conn_zone $binary_remote_addr zone=conn_limit:10m; server { listen 443 ssl; server_name your-domain.example.com; ssl_certificate /etc/ssl/certs/fullchain.pem; ssl_certificate_key /etc/ssl/private/privkey.pem; # 大请求体限制 client_max_body_size 64m; # API Key 校验:从请求头取 X-Api-Key if ($http_x_api_key != "your-secret-key") { return 401; } location / { limit_req zone=api_limit burst=20 nodelay; limit_conn conn_limit 4; proxy_pass http://127.0.0.1:8000; 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_read_timeout 120s; proxy_send_timeout 120s; } } server { listen 80; server_name your-domain.example.com; return 301 https://$host$request_uri; }有人会问为什么用 if 判断 API Key 而不是更复杂的 auth_request 模块。简单场景下 if 足够,逻辑直观,出问题一眼能定位。真到需要对接企业账号体系时,再上独立鉴权服务也不迟,不用一开始就上重武器。
4.3 更稳妥的多用户鉴权方案
团队内部如果所有人都用一个共享静态 Key,责任边界会很模糊:说不清是哪个调用方超了限额,也没法单独撤销某个人的权限。我们的做法是在 Harness 外层再加一层 Token 校验,每个人拿自己的 token,Nginx 校验 token 合法性,日志里记录调用者标识。
如果团队成员多、权限细分,可以引入轻量 OAuth 代理,把认证交给已有账号体系,但前提是你们已有身份源可用。对大多数小团队,静态 API Key 加 Token 白名单已经足够了。Token 白名单可以是一个简单的只读文件,Nginx 配置里用 map 指令加载,维护成本很低。
4.4 限流参数怎么调不误伤正常使用
限流是最容易拍脑袋配错的部分。我一开始配了 rate=2r/s,结果同事写脚本循环请求,没跑几步就被 503 拍回来了。后来调到 rate=10r/s、burst=20,单个客户端短时间并发就不再被误伤,恶意刷量又能被有效拦截。
具体数值取决于模型并发和显存,原则是:限流阈值要高于正常峰值,但低于能把服务拖垮的量级。比如正常团队最多同时 5 个请求在跑,模型并发上限 4,那 Nginx 侧连接数限 4 就很合理,超过的直接排队或拒绝。
5. 从本机调试到公网放行的完整验证时序
5.1 分层验证,别直接拿公网域名糊脸测
我的习惯是先建立一条分层验证链:本机 Harness 通,本机 Nginx 通,服务器外访问通。每一层确认无问题,再往下一层走。这种做法的原因是网络问题一旦叠加,排错难度会指数级上升,分层验证可以把问题牢牢隔离在某一层。
第一步,本机 Harness 通,上一节已经做了。
第二步,本机走 Nginx 验证:
curl -k https://127.0.0.1/v1/chat/completions \ -H "Content-Type: application/json" \ -H "X-Api-Key: your-secret-key" \ -d '{"model": "deepseek-chat", "messages": [{"role": "user", "content": "ping"}], "stream": false}'注意这里用了 -k 跳过证书校验,因为请求目标是 IP 而不是域名,证书校验一定会失败,跳过它我们只验证转发链路。这一步通过,说明 Nginx 到 Harness 的请求通路没问题。
第三步,才轮到公网真端口验证。此时在本地电脑通过域名发起 HTTPS 访问,带不带 Key 都要测一遍:不带 Key 预期返回 401,带错 Key 预期也返回 401,带对 Key 预期正常返回。
5.2 什么时候改防火墙和安全组
很多教程把安全组放行放在最前面,我建议反过来:先把服务全部跑起来,确认 Nginx 正常监听 443,再放行防火墙。顺序反过来不是不行,只是在排错时会多一层干扰因素。
正确做法是先在服务器内测试回环访问,确认 Nginx 正常后,再到控制台安全组放行 443 和 80 端口,然后用手机流量做一次真外网访问。手机流量之所以重要,是因为它绝对不经过内网 DNS 和 NAT,能真实反映公网可达性。别用办公室同一出口的 WIFI 测,浏览器缓存和局域网路由会影响判断。
5.3 全链路验证清单
我整理了一份可以照着勾的清单,上线前过一遍,能挡住绝大多数低级问题:
| 检查项 | 预期结果 |
|---|---|
| 本机 curl 127.0.0.1:8000 | 正常 JSON 返回 |
| 本机 curl -k https://127.0.0.1 | 正常 JSON 返回 |
| 不带 Key 访问公网 | 401 |
| 带错误 Key 访问公网 | 401 |
| 带正确 Key 访问公网 | 200,正常返回 |
| 日志出现调用记录 | 包含时间、来源 IP、Key 标识 |
| 连续高频请求 | 触发限流,返回 503 |
| 长文本流式请求 | 不中断,完整返回 |
6. 稳定运行的关键:踩坑记录与运维配置参考
6.1 最大的坑:后端端口裸奔在公网
第一次部署时我图省事,Harness 直接监听 0.0.0.0:8000,安全组也顺手放行了 8000。结果第二天一早看监控,发现一堆来自陌生网段的请求,有人在批量扫描 8000 端口。虽然模型服务没崩,但探测流量已经浪费了不少带宽和日志空间。发现问题后我第一时间删掉安全组里的 8000 规则,把 Harness 监听地址改成 127.0.0.1。
这个坑给我的教训是:任何服务默认都不要想着"先开着,后面再关"。公网扫描是持续不断的,防护必须在暴露前做完,而不是暴露后补救。
6.2 请求体大小与流式超时
Nginx 默认 client_max_body_size 是 1M,对普通 API 够用,但 AI 对话中 prompt 一长,一次带几千 tokens 就超了,直接返回 413。另一个隐蔽点在于流式输出场景:如果 proxy_read_timeout 保持默认 60s,模型生成速度稍慢,客户端会看到一个 504 中断,生成到一半的响应直接作废。
这两个参数我在配置里都做了调大处理,问题才消失。如果你后续也遇到长 prompt 被拒或流式中断,优先检查这两个值。
6.3 OOM 与并发参数之间的平衡
推理服务跑着跑着进程被杀,十有八九是显存不够。我遇到过模型加载成功、但并发请求一上来就 OOM 的情况,根因是推理启动参数里的并发数设得比显存余量还高。后来把并发调低,并给进程加了显存监控。显存使用率超过 95% 时自动告警,虽然不能自动扩容,但至少不会等到服务挂掉才发现。
6.4 日志轮转与调用审计
公网服务必须留日志,但日志不能无限涨。我配了按天切割加保留 30 天的轮转策略。另外在 Nginx access log 里专门记录了调用来源 IP、Key 标识和请求体大小,这样真正发生滥用时,至少能回溯到具体时间和调用方。
Nginx access log 的格式可以自定义,加入请求头和响应状态码,后面做统计时候很方便。建议从一开始就把日志字段定全,后面补会漏数据。
6.5 systemd 托管与开机自启
最后一步,把 Harness 交给 systemd 管理,意外退出后能自动拉起,服务器重启后也能自动恢复服务。
[Unit] Description=Deepseek Harness After=network.target [Service] User=deployer WorkingDirectory=/data/harness ExecStart=/data/harness/venv/bin/python run.py --config config.yaml Restart=always RestartSec=10 [Install] WantedBy=multi-user.target写好后执行:
sudo systemctl daemon-reload sudo systemctl enable harness.service sudo systemctl start harness.service到这里,整套部署就算完成了。回头看最花时间的其实不是模型本身,而是把"内网能跑"升级成"公网能安全访问"这层壳。我个人操作下来最深的体会是:先把链路本机跑通,再上公网鉴权,最后调限流和超时,顺序不要乱;后端绑定回环地址这个习惯,值得写进你所有的部署清单。后来团队又加了几个新场景,也就是改改 Nginx 的 location 和 Key 白名单,核心架构一直没动过,这套方案确实够扛事。