把一个 Agent 服务放到公网
2026 年 9 月。服务在本机跑得好好的,一旦放到公网,问题全都变成了"登录不上"。
先说结论
自建服务上公网,真正花时间的不是"怎么让它能从外面访问",而是"访问进来之后为什么登不上去、为什么重启一次就失效"。下面这几条是我踩过之后记住的。
进程级随机的密钥
这个服务的会话密钥是每次进程启动时随机生成的,不落盘。所以在本地用完全没问题——进程不重启,密钥就不变。但一旦放到服务器上由进程管理器托管,情况就变了:服务重启一次,之前发出去的所有会话凭据全部失效,表现就是"昨天还好好的,今天打开就是未授权"。
我一开始以为是浏览器缓存的问题,反复清 cookie、换浏览器,最后才发现是服务端自己在重启时换了钥匙。解决办法是让凭据持久化到固定文件,重启后继续用同一份。
教训:把服务交给进程管理器托管之前,先确认它的密钥/凭据是持久化的还是每次启动随机生成的。
Cookie 的作用域比想象中讲究
另外两个坑:
- 会话 cookie 设置了
SameSite=Strict,这意味着通过外部链接跳进来时不会带上 cookie,必须直接在地址栏输入地址打开才正常。这不是 bug,是安全设计,但用户不知道,只会说"点了链接登不进去"。 - 反过来,如果随随便便就把
SameSite放开、把域名作用域放宽,等于把自己暴露在被跨站请求伪造的风险里。最后还是选择保留严格策略,把"请在地址栏直接打开"写进说明。
有些行为是前端的判断,服务端没有开关
服务在"非本机回环地址"访问时,会主动把一部分配置项变成只读——原因是它假定公网部署下管理员不该通过网页改配置。这个判断完全在前端,服务端没有对应的开关,所以想改也没得改,只能改部署结构。
这提醒我一件事:评审一个服务的部署文档时,要看它在什么条件下会降级功能,而不是等上线之后发现某个功能点不动了再去翻源码。
关于 SSH 隧道
遇到登录问题时,最省事的做法是在本机和服务之间拉一条 SSH 隧道,让公网流量看起来像是从本机发出的——所有"非回环地址"的限制立刻消失。
我没有采用它。原因很直接:这不是在解决问题,而是把问题藏起来,而且顺带把一台服务器的安全边界让出去了。最后走的是正经的反向代理加进程托管,把会话问题从根上修掉。
现在的部署长这样
- 服务由进程管理器托管,开机自启、崩溃重拉,日志落到固定位置
- 凭据持久化,重启不影响已发出的会话
- 反向代理负责域名与 HTTPS,服务本身只监听本机端口
- 访问方式写清楚:从地址栏直接打开,不要用转发链接
回头看,这一整套其实和"部署一个 AI 服务"关系不大,它就是最普通的运维常识——只是平时自己玩的时候,没人逼你想这些。