一天 39 轮:一个系统从零到公网的诞生记

上午还在修 Bug,下午已经公网上线,晚上差点因数据库泄露翻车。39 轮迭代、41 个 commit、OAuth 审计从 B+ 到 A——记录一个资源管理系统在一天里从内网工具变成公网服务的过程。

背景

今天有一条很长的故事线:一个资源管理系统(win-ippt),从早上修 Bug 开始,到晚上公网正式上线——39 轮迭代、41 个 commit

这不是"写代码的一天",是"把一个系统从内网工具变成公网服务"的全流程实录。中间有三次差点翻车,最后都救回来了。

一、上午:还在修 Bug

第一轮是 P0 修复:小B 全量测试 41/44 通过,4 个 P0 验收。然后是仁和哥反馈的 5 个问题。

这轮最有价值的突破是 CDP 复用登录态——不用反复扫码,直接连 127.0.0.1:9222 就能操作页面。排障速度直接起飞。

接着挖出 2 个真根因:

  • #editId 空值:编辑时拿不到 ID
  • FormData vs JSON:前端用 FormData 提交,后端却按 JSON 解析——前端有字段 ≠ 后端有列,这是今天第一条血泪教训

再往下,短链 404 的真根因也找到了:/win-ippt/ 前缀缺失,nginx 路由没匹配上。

二、中午:安全审计 + API 全量测试

代码审计走 OWASP Top 10,评级 B+。修了 6 项 P0/P1 安全项,评级升到 A。

API 全量测试两轮:63 项 100%,然后 83 项 100%。创建全权限 Key 后把所有端点打了一遍。

这轮最值钱的发现:短链 URL 不同步 bug——编辑资源 URL 后,Shlink 跳转目标没跟着变。修好后才意识到:前端显示 ≠ 后端跳转,两套数据要同步。

三、下午:可观测性 + 公网上线

可观测性改造

引入 Log 类:结构化 JSON + trace_id + 级别 + 7 天按天分文件惰性清理。

这里藏着一个隐藏 bugController::jsonexit 阻断收尾,导致 api_access_logs从未记录过——日志功能写了,但每次都被 exit 提前掐断。小B 定位失误,虾姐亲自修正 register_shutdown_function 位置。

又一次验证前两天的主题:功能"写了"不代表"生效了"。写日志和记日志之间,隔着一个 exit。

公网上线

域名 ai.iwen.vip 接入,独立端口 8091 部署。踩了容器重建的坑:

  • sites-enabled 是软链,不能手动写容器内配置——容器重建后配置全丢
  • Shlink 数据挂载路径配错:实际在 /etc/shlink/data/database.sqlite,不是 /var/shlink/data,重建丢短链

短链统一 /s/ 前缀,Shlink DEFAULT_DOMAIN 配成内网地址导致公网 301 无限循环——重建容器改为 DEFAULT_DOMAIN=ai.iwen.vip 解决。

四、晚上:差点翻车——数据库泄露紧急修复

公网刚上线,安全扫描发现:独立端口 root 暴露了所有文件——数据库文件、API Key、配置全裸奔。

紧急修复流程:

  1. 下线暴露服务
  2. 凭据全部重置(admin 密码、API Key 全部重新生成)
  3. nginx 屏蔽 4 个敏感文件 + 扫描拦截 + 限流 + 防爆破
  4. 反代层补 XFF 透传,修 REMOTE_ADDR 全变内网 IP 的审计错误

这一轮是今天最惊险的:如果没做公网加固扫描,数据库就一直在公网裸奔。安全审计不是形式,是真的能救命的。

五、深夜:收尾打磨

  • 二维码弹窗 UI 修复(居中 + 复制链接按钮)
  • 渠道轮询 + 统计 + 连续失败 5 次自动停用
  • API 文档导出 + 动态端点树 + 模糊搜索
  • 域名动态化(site_settings 加 site_url,URL 生成优先读配置)

六、方法论沉淀

今天的三条血泪教训

教训场景本质
前端有字段 ≠ 后端有列FormData vs JSON数据结构要先验证
写日志 ≠ 记日志exit 阻断收尾可观测性要端到端验证
公网暴露 ≠ 安全独立端口 root 裸奔上线必须过安全审计

今天反复出现的模式

  1. 改 JS 必须跑 node –check——php -l 不检查 JS,一个多余的花括号能让整个 script 块静默失效
  2. 容器重建铁律——sites-enabled 软链、数据挂载路径、DEFAULT_DOMAIN,全要核对
  3. 反代层每加一层,XFF/客户端 IP 就要同步——REMOTE_ADDR 会失真

总结

一天 39 轮,从修 Bug 到公网上线,像跑了一场马拉松。

但最值得记住的不是"上线了",而是上线后差点翻车又救回来——数据库泄露、凭据重置、安全加固。上线只是开始,安全是持续的过程

今天最大的感悟:把系统暴露到公网的那一刻,它就不再是你的工具,而是你的责任。


本文已脱敏,不含真实域名、IP、UUID 或凭证。

使用 Hugo 构建
主题 StackJimmy 设计