本地写 Markdown,git push 后自动上线:我的双语博客发布流程
这篇文章解决什么问题
很多个人博客卡住,不是因为不会搭站,而是因为发布链路太重。每写一篇文章都要手工改配置、手工构建、手工上传,久而久之内容生产就断掉了。
我这次把自己的博客整理成一条更顺手的流程:本地直接写 Markdown,提交到 GitHub 后由 GitHub Actions 自动构建和发布。这样写文章这件事,才更像持续做内容,而不是每次都做一次运维。
适用场景
- 你做的是个人博客、技术内容站或轻量文档站
- 你希望文章以 Markdown 文件保存在仓库里
- 你不想上 WordPress,也不想维护重后台
- 你希望中英双语内容能长期维护,而不是靠手工映射
如果你更想要在线后台、多人协作编辑和可视化审核流,那这套方式就不是最优解。
最终效果
这套链路跑通之后,发一篇新文章只需要这几步:
- 本地生成中英双语文章骨架
- 编辑两份 Markdown
- 本地预览确认内容和排版
git push origin main- GitHub Actions 自动部署上线
也就是说,内容生产和部署已经被拆开了。你只关心写文章,发布动作由自动化接手。
环境准备
我当前这套博客栈是:
- 框架:
Astro - 内容层:
astro:content - 内容格式:
Markdown - 部署方式:静态产物发布
- Web 服务:
Nginx - 自动部署:
GitHub Actions
内容目录是双语分开的:
src/content/posts/zh-cn/*.md
src/content/posts/en-us/*.md
同一篇文章的中英文文件共享一个 path,站点会自动生成:
- 中文:
/posts/<path>/ - 英文:
/en/posts/<path>/
具体步骤
1. 先把内容模型定死
如果一开始内容模型不稳定,后面你每加一篇文章都要补逻辑。
我现在把博客的文章、页面、分类、资源都统一放进了 astro:content,关键点有两个:
- 文章用
path - 页面和分类用
key
这样做的好处是,新增内容时只增加 Markdown 文件,不再去碰路由映射代码。
2. 提供一个文章脚手架命令
如果每次发文章都手工复制旧文件,效率很快就会下降。
我在项目里补了一个脚本:
npm run new:post -- "markdown-blog-publish-workflow" "本地写 Markdown,git push 后自动上线:我的双语博客发布流程" "Write Markdown Locally, Deploy on git push: My Bilingual Blog Publishing Workflow" writing
执行后会直接生成两份草稿:
src/content/posts/zh-cn/markdown-blog-publish-workflow.md
src/content/posts/en-us/markdown-blog-publish-workflow.md
默认是:
draft: true
这很重要,因为它能防止你写到一半就被自动部署出去。
3. 本地只负责写作和预览
写文章时,我只做两件事:
- 编辑 Markdown
- 本地
npm run dev
浏览器里主要看这些点:
- 首页是否出现新文章
- 中文和英文详情页是否都可访问
- 分类和标签是否正常聚合
- 标题和描述是否适合 SEO
如果这一步通过,后面其实就不该再手工 SSH 发布了。
4. 把部署动作交给 GitHub Actions
这一步是整个流程能不能真正省事的关键。
我现在的工作流是:
- push 到
main - Actions 自动
npm ci - 自动
npm run build - 打包
dist - 通过 SSH 上传服务器
- 解压到新的
releases/<timestamp>-<sha> - 切换
current - 做一次公网可访问性校验
这意味着文章发布已经变成标准 CI/CD 流程,而不是依赖我手工操作。
5. 生产服务器只做静态托管
我的一个明确原则是:服务器不负责构建,只负责托管。
这样有几个直接好处:
- 服务器更稳定
- 构建环境更统一
- 回滚更简单
- 出问题时能快速分层定位
目前线上结构大概是:
/var/www/aitokenhacks.com/releases/<release-id>
/var/www/aitokenhacks.com/current
每次发布都只是在切换软链接,不是覆盖线上目录。
6. 给自动部署补诊断信息
自动化不是写完 workflow 就结束了。真正有用的自动化,出错时要能快速说明白问题。
所以我后来又给 workflow 补了几类诊断:
- 缺少哪个 Deploy Secret
- SSH 是否能连通
- 远端目录是否存在
current最终切到了哪个 release
这样以后如果部署失败,不会只看到一个抽象的红叉,而是能很快知道问题是在 GitHub Secrets、SSH、目录权限,还是公网验证。
常见问题
为什么我不直接上在线后台
因为我现在这个站的重点是内容积累和 SEO,而不是编辑器体验。
Markdown 文件化管理有几个我更看重的优点:
- 全量进入 Git
- 可回滚
- 可审阅
- 内容和代码结构一致
- 不依赖第三方后台可用性
双语内容为什么不用单文件混写
因为单文件里塞两套 frontmatter 和两套正文,维护成本很快会上来。
我最后选的是“双文件,同 path”的方式:
- 符合 Astro 内容集合的天然工作方式
- 正文维护最直观
- 不需要额外翻译映射层
自动部署失败最常见的原因是什么
我这次实际踩到过的主要有两类:
- GitHub Actions 计费或额度问题,作业直接起不来
- Deploy Secrets 没配对,SSH 配置阶段直接失败
所以我现在会优先检查:
- Actions 是否真的开始执行
- Secrets 是否齐
- SSH 用户和密钥是否有效
- 远端目录权限是否允许发布
最后总结
如果你也在做个人技术博客,我非常建议把“写作”和“发布”拆开。
写作时,只管内容质量。 发布时,让 CI/CD 去做重复动作。
当你能把发文动作压缩成“本地写 Markdown,然后 git push”,内容站才真正进入可持续维护的状态。