
如果你也到了需要把本地的大模型推理服务搬到公网的阶段这篇东西应该能帮你少熬几个夜。事情起因是内部工具要跑一个基于 Deepseek 的 Harness 推理服务让不在同一办公地点的同事也能通过公网安全访问。真做下来才发现云服务器部署 Deepseek Harness 全流程本身不复杂真正磨人的是公网鉴权访问这层安全网——既要让外网用起来顺畅又要挡住扫描、滥用和误操作。这篇文章会把完整流程拆开讲服务器怎么选、模型权重怎么准备、Harness 服务怎么起、公网 HTTPS 和鉴权怎么配、内网调试到公网放行的顺序是什么最后是我踩过的一些坑和稳定运行后的配置参考。适合有一定 Linux 基础、打算把私有 Deepseek 服务开放给团队使用的开发者。如果只是本机跑 demo公网部分可以跳过但部署和验证思路同样值得参考。1. 为什么要把 Deepseek Harness 放到公网需求背景与整体架构1.1 三个绕不开的现实问题我这次部署的起因很朴素某个内部工具需要稳定的文本推理能力但数据不能全部走外部大模型 API刚好 Deepseek 有可本地部署的开源权重于是决定自建。最初的想法特别简单内网跑起来就行。可实际情况是团队不在同一个办公区有人在外地、有人在家服务如果只绑在办公网内这些人就全被挡在门外。于是需求从“本地能跑”变成了“公网能安全访问”。第二个问题是多人共用。一旦多个人同时请求没有统一入口的话每个人各连底层模型端口显存很快会被打满而且一点可观测性都没有。Harness 这层实际上承担了请求排队、会话区分和调用统计相当于给模型加了一个调度前台。没有这层封装后面做鉴权也根本没地方挂。第三个问题是安全。公网意味着任何人都可能扫到你的服务器 IP模型服务如果裸露在公网轻则被刷爆资源重则被当成免费 AI 接口滥用。所以公网放行不是简单开个端口必须配一整套鉴权、限流和访问控制方案。1.2 整体架构一句话讲清楚整个链路可以抽象成三层最外层是 HTTPS 入口中间是鉴权网关最里面是 Harness 推理服务。客户端请求先经过域名解析落到云服务器公网 IPNginx 在 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 拖垮服务首次启动建议用前台模式跑日志直接打到终端确认模型加载完成后按 CtrlC 再改用 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 zoneapi_limit:10m rate10r/s; limit_conn_zone $binary_remote_addr zoneconn_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 zoneapi_limit burst20 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 校验每个人拿自己的 tokenNginx 校验 token 合法性日志里记录调用者标识。如果团队成员多、权限细分可以引入轻量 OAuth 代理把认证交给已有账号体系但前提是你们已有身份源可用。对大多数小团队静态 API Key 加 Token 白名单已经足够了。Token 白名单可以是一个简单的只读文件Nginx 配置里用 map 指令加载维护成本很低。4.4 限流参数怎么调不误伤正常使用限流是最容易拍脑袋配错的部分。我一开始配了 rate2r/s结果同事写脚本循环请求没跑几步就被 503 拍回来了。后来调到 rate10r/s、burst20单个客户端短时间并发就不再被误伤恶意刷量又能被有效拦截。具体数值取决于模型并发和显存原则是限流阈值要高于正常峰值但低于能把服务拖垮的量级。比如正常团队最多同时 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] DescriptionDeepseek Harness Afternetwork.target [Service] Userdeployer WorkingDirectory/data/harness ExecStart/data/harness/venv/bin/python run.py --config config.yaml Restartalways RestartSec10 [Install] WantedBymulti-user.target写好后执行sudo systemctl daemon-reload sudo systemctl enable harness.service sudo systemctl start harness.service到这里整套部署就算完成了。回头看最花时间的其实不是模型本身而是把内网能跑升级成公网能安全访问这层壳。我个人操作下来最深的体会是先把链路本机跑通再上公网鉴权最后调限流和超时顺序不要乱后端绑定回环地址这个习惯值得写进你所有的部署清单。后来团队又加了几个新场景也就是改改 Nginx 的 location 和 Key 白名单核心架构一直没动过这套方案确实够扛事。