把每日科技日报改成服务器自运行
背景
这次调整不是为了“换一种自动化工具”,而是为了解决两个实际问题:
- 当前机器访问 GitHub 不稳定,
git push和 GitHub Actions 触发链路经常中断。 - 日报如果只在远端生成,但我后续继续从本地上传
dist,服务器上新增的新闻内容又可能被下一次手动发布覆盖掉。
原来的设计里,日报生成和站点部署都依赖 GitHub。理论上流程清晰,但在网络不稳定时,最先失效的恰好就是自动发布链。
所以这次没有继续在 GitHub 侧修补,而是把整条链路收回到服务器本机:抓取新闻、生成 Markdown、更新 RSS / sitemap、构建站点、原子发布,全部在服务器侧完成。
为什么改成服务器自运行
目标其实很简单:
- 日报每天能稳定跑。
- 手动发版和自动日报走同一条发布链。
- 自动生成的内容不会被后续部署覆盖。
这意味着不能只改“定时任务在哪里触发”,还要一起改“站点最终以谁为准”。
如果只是把 GitHub Actions 换成别的 CI,而站点仍然靠本地上传 dist,问题并没有真正解决。因为构建时读取的仍然是本地源码,而不是服务器上已经生成过的日报 Markdown。
所以这次的核心决定其实是两条:
- 每日新闻任务改为服务器定时执行。
- 手动发布也改成“同步源码到服务器,再由服务器本机构建并上线”。
调整后的链路
现在的发布链是这样的:
本地修改源码
↓
同步源码到 /opt/techloop-blog
↓
服务器保留 ai-dev-daily-*.md
↓
服务器本机 build
↓
原子切换 /var/www/blog
日报任务则独立跑在同一份服务器源码上:
08:10 定时触发
↓
抓取 RSS
↓
筛选前一自然日新闻
↓
调用 OpenAI 整理中文日报
↓
写入 src/posts/ai-dev-daily-YYYY-MM-DD.md
↓
生成 RSS / sitemap
↓
构建并发布
这样做有一个直接结果:自动日报和手动发版不再是两套互相覆盖的来源,而是统一到同一份服务器工作目录。
这次实际补了什么
这次没有改前端展示逻辑,首页、动态页和文章页仍然沿用现在的 category: news 内容入口。真正变的是自动化层。
主要新增了三类脚本:
- 服务器日报入口:负责生成日报、识别
skip、写日志。 - 服务器构建发布入口:负责
npm run build和原子切站。 - systemd 定时任务:负责每天
08:10 Asia/Shanghai触发。
同时本地发布脚本也改了逻辑:
- 以前是本地 build 后直接上传
dist。 - 现在是把源码同步到服务器,再由服务器本机构建上线。
这个调整看起来比“只改一个 cron”大一些,但它解决的是整条链路的一致性问题。
运行结果
这次上线后,已经手动验证过两个场景。
第一种是指定历史日期回放:
scripts/deploy/server-daily-news.sh --date 2026-05-22
它成功生成了:
src/posts/ai-dev-daily-2026-05-22.md
并完成了构建与上线。
第二种是直接触发当天默认任务。系统会去处理前一个自然日的内容,如果最终唯一新闻不足 3 条,就正常跳过:
skip: only 1 unique items for 2026-05-25
这里的 skip 不是错误,而是当前策略本身的一部分:宁缺毋滥,不为凑数发一篇质量过低的日报。
过程里遇到的两个问题
1. OpenAI 中转站只支持 chat completions
这次日报生成用的是 OpenAI 兼容接口,但实际接入的是一个中转站。它只支持 /v1/chat/completions,而且在某些情况下还要求 stream: true。
所以日报脚本在调用层做了兼容:
- 支持自定义
OPENAI_BASE_URL - 改用 chat completions
- 中转站要求流式时自动回退到流式请求
这样才让脚本能在当前环境里稳定跑通。
2. 服务器 Node 版本过低
服务器原来是 Node 18,构建虽然勉强能跑,但依赖已经提示 react-router 要求 >=20。
最后还是把服务器升级到了 Node 20,再重新验证了日报脚本和 systemd 触发链。这个问题如果不提前处理,后面自动任务会存在延迟爆雷的风险。
现在的状态
目前这条链路已经满足最初目标:
- 日报不再依赖 GitHub Actions。
- 自动日报和手动发版走同一条服务器发布链。
- 自动生成的新闻内容不会再被下一次本地部署覆盖。
- 少于 3 条新闻时任务成功跳过,不会生成凑数稿。
从维护角度看,这比继续折腾 GitHub 网络问题更直接。发布链越靠近真正提供服务的那台机器,越容易控制,也越容易排查。
后续还可以继续优化什么
现在这版已经能用,但还可以继续往前走两步:
- 扩大 RSS 来源,减少“当天不足 3 条”的情况。
- 增加一个回退策略,例如目标日期新闻不足时,再补看近 48 小时窗口。
- 给自动生成的日报加更明确的内部标识,便于后台或后续统计处理。
- 再补一层监控,例如任务失败时发一条简单通知。
不过这些都属于下一阶段。对当前博客来说,更重要的是先把“自动生成并稳定上线”这件事做扎实。
See also
- 一次完整的 WSL2 安装排障:从 BIOS、TPM 判断到 Windows 11 修复安装 2026-07-07
- 把一个 SPA 博客补成可预渲染、可同步、可持续部署 2026-05-29
- 把宿舍 Windows 主机改成可远程训练的 WSL 工作站 2026-05-27
- Chrome 一打开就跳到 360 导航页?按这份手册一步步修复 2026-05-20
- 博客改版记录:首页、栏目页与轻量 3D 2026-05-16