我以为今天是在收尾一个后台,结果后来更像是在追一条网络链路。
这件事一开始看上去并不复杂。
博客已经有 Hugo 的内容结构,也已经有脚本化的新建文章、封面、发布校验。我今天要补的,只是一个网页后台:能登录、能写文章、能上传配图、能把内容提交回 GitHub,然后继续走现有的 Actions 发布链路。
这部分其实很快就搭起来了。
admin/ 子应用、文章列表、新建编辑页、图片上传、GitHub Contents API 提交、部署状态查询,连同 Caddy 反代和 systemd 服务文件,都在预期里推进。到这里我还觉得,今天的主要工作大概就是把后台收口,再整理一下部署说明。
真正开始变慢,是在“登录”这一步。
先是 GitHub OAuth 的回调地址对不上。看起来只是一个 redirect_uri 的问题,但它背后牵着好几层:生成授权地址时的基地址、线上域名、回调路径、部署环境变量、以及 GitHub OAuth App 本身的配置。修掉这层之后,登录按钮终于能把人送到 GitHub,可回调回来还是失败。
后来问题继续往下钻。
我按官方文档把 token 交换过程重新对齐了一遍:授权入口不再走会引出预取问题的写法,回调阶段改成更直接的请求方式,参数编码也重新核过。表面上代码已经没有明显问题了,可线上还是不稳定。于是这件事开始从“应用逻辑排错”,变成“服务器到底能不能稳定摸到 GitHub OAuth 端点”。
这时候转折才真正出现。
腾讯云那台机器并不是完全不能访问 GitHub。普通页面有时能打开,api.github.com 也未必全断,但 github.com/login/oauth/access_token 这条链路并不稳定。也就是说,后台代码已经写完了,OAuth 配置也基本对上了,可真正决定登录是否成功的,变成了服务器的出站能力。
这一下,问题的中心就彻底变了。
我中间确实走过一条临时路子,用反向 SSH 隧道把 token 交换借到本机出口上,先把链路打通。这招能救急,但不适合作为正式部署,因为只要本机休眠、重启,或者隧道进程退出,后台登录就会一起掉线。
所以后面真正有效的工作,不是继续改页面,而是回头去找我手上已经有的代理资产。
在 C:\AITemp\Servers_and_Proxies 里,现网代理和 Clash 订阅的资料其实一直是完整的:权威入口文件、当前正式 VPS、现用的 Clash YAML、以及 3X-UI 的维护 runbook 都在那里。顺着这条线回去之后,事情突然简单了很多。我没有再临时拼一个新方案,而是把现成那套稳定的代理出口重新接到腾讯云服务器上,再通过 systemd drop-in 只给 blog-admin 这个服务挂代理环境变量。
到那一刻为止,这个后台才算真的“写完”。
因为后台能不能上线,从来就不取决于你是不是把表单写出来了。真正的完成,是用户点击 GitHub 登录时,请求能稳定地从浏览器走到你的服务,再从你的服务走到 GitHub,然后带着可验证的身份回到文章列表页。
我今天最强烈的感受也是这个。
很多时候,我们会把“项目完成度”理解成代码完成度,尤其是做这种内容后台的时候,很容易把注意力全部放在编辑器、上传接口、发布按钮这些看得见的部分。但只要它一旦上线,真正决定成败的,往往就不是这些最显眼的代码,而是那些平时被当作背景的东西:域名、回调地址、服务进程、环境变量、出站网络、代理策略。
所以今天最值得记下来的,并不是“我又做了一个后台”。
而是我又被提醒了一次:对线上系统来说,真正的最后一公里,常常不是功能,而是链路。
后台本身当然也值得写。这个版本已经能支撑我自己写文章、上传封面和正文配图、保存草稿、直接提交回仓库,再复用现有 Hugo 发布流程。它确实把“写博客”这件事从手工改文件,推进成了一个可持续的入口。
但如果只写到这里,这篇记录就会变得太像 changelog。
而今天真正让我记住的,是另一个更朴素的判断:当你觉得功能已经差不多的时候,最好先别急着庆祝。先看一眼那条从浏览器到服务、再到外部平台的真实链路。很多项目不是死在功能没写完,而是死在“本来以为这一步不会出事”的地方。
