用 Astro 重建我的博客:从 Laravel 到「内容即文件」
为什么要重建
原来的博客跑在 Laravel + MySQL 上。写篇文章要进后台、建表、存字段,富文本塞进数据库,图片散落在 storage/。维护成本越来越高,而且脱离了数据库就什么都不是——备份、迁移、换服务器都绑死了那套运行时。
我一直想要的其实很简单:内容即文件。文章和笔记就是磁盘上的 Markdown,版本化在 Git 里,构建时自动生成页面。于是这次下定决心,把它重构成一个纯前端的 Astro 静态站点。
技术选型
| 维度 | 旧站 | 新站 |
|---|---|---|
| 框架 | Laravel + Blade | Astro 5(纯静态输出) |
| 内容存储 | MySQL 表 | 磁盘上的 Markdown 文件 |
| 图片 | storage/app/public + 软链 | public/ 下直接托管 |
| 管理后台 | 自写 Laravel 后台 | Decap CMS(Git-backed) |
| 部署 | 服务器跑 PHP-FPM | 自托管 + 宝塔面板 + Nginx |
| 自动部署 | 手动 | GitHub push → WebHook 自动构建 |
选 Astro 是因为它天然契合「内容即文件」:文章和笔记用内容集合(Content Collections)管理,frontmatter 定义元数据,正文写 Markdown,构建期做类型校验,几乎零运行时。
内容模型
站点分两类内容,对应两个目录:
- 文章(
src/content/articles/):长教程、技术文,frontmatter 含title/date/description/category/series。 - 笔记(
src/content/notes/):短知识卡、摘记,按日期倒序,frontmatter 含date/tags/images。
阅读时长与日期格式化都在构建期算好,页面只负责渲染。
管理后台:Decap CMS
既然内容就是 Git 仓库里的文件,后台最自然的选择是 Decap CMS——它直接把编辑操作变成往仓库提交 Markdown 的 Git commit,不需要自己写任何后端或鉴权服务。
- 后台挂在
https://itcwc.com/webadm/,登录走 GitHub OAuth(无需自建账号体系); - 文章、笔记、站点设置都是可视化编辑,保存即
git commit; - 上传的图片落到
public/uploads/,随仓库一起部署,线上不裂图。
这比当初设想的「自写 Astro API + HMAC 会话 + Cloudflare Functions」轻得多,也安全得多——没有暴露在公网的写接口。
部署:自托管 + 宝塔
站点产出的是标准静态 dist/,交给 Nginx 托管即可。自动部署用宝塔 WebHook 方案:
- 仓库配置 Webhook,push 时打向宝塔的钩子地址;
- 钩子脚本执行
git pull && pnpm install && pnpm build; - Nginx 站点根目录指向
dist/,新内容即刻上线。
Decap 提交内容本质也是一次 git push,所以同样的流程会自动触发重建——管理操作和部署完全解耦。
旧站数据迁移
老站数据从 MySQL 导出为 .sql,写脚本按内容模型映射:
contents表里type='article'的 13 条 →src/content/articles/{slug}.mdtype='note'的 13 条 →src/content/notes/{日期}-{id}.md- 文章配图(46 张)原样搬进
public/data/image/;笔记图片搬进public/uploads/ - 老站没有分类/专栏概念,迁移时按内容主题生成了分类与专栏字段
正文本身是 Markdown,所以转换近乎无损,图片路径保留原引用即可。
结语
现在写博客就是往目录里丢一个 .md,git push 之后自动上线。没有数据库、没有运行时依赖、没有后台服务,所有内容都在 Git 里版本化。这篇本身,就是迁移完成后的第一篇正式记录。