
用 Astro + Cloudflare Pages 搭一个零成本博客
这个站点本身就是按下面这套方案搭的。整个过程只有一笔支出:域名年费(几十到一百块)。构建、CDN、证书、自动部署全部免费。
选型:为什么是静态站
先把三种方案的取舍摊开。这里的成本不含自己投入的时间。
| 方案 | 年成本 | 优点 | 代价 |
|---|---|---|---|
| 静态站 + Pages | 域名 | 快、免运维、Git 版本管理、Markdown 原生 | 没有后台,评论/搜索要外挂 |
| 自托管(WordPress / Halo) | 域名 + 电费 | 有后台和插件生态 | 公网暴露、升级、备份全自理,机器挂站就挂 |
| 托管方案(Ghost 等) | $100+ | 零运维 | 月费高,国内访问慢 |
个人博客的瓶颈从来不是“功能不够”,而是“三个月后还想不想写”。静态站把维护成本压到接近零,这是它唯一的、但也是决定性的优势。
技术栈
- Astro:默认零 JS,内容站的最优解,需要交互的地方可以局部挂组件
- Markdown / MDX:文章就是文件,不依赖任何编辑器
- Cloudflare Pages:连 GitHub 仓库,push 自动构建,全球 CDN,免费 SSL
目录结构
真正需要关心的只有三个位置:
blog/
├─ src/
│ ├─ content/blog/ ← 所有文章(.md / .mdx)
│ ├─ consts.ts ← 站名、作者、导航、评论开关
│ └─ styles/global.css ← 全站样式与主题变量
├─ public/ ← 静态资源(favicon、robots.txt)
└─ astro.config.mjs ← 域名、语法高亮、字体
写一篇文章
在 src/content/blog/ 下新建 .md,文件名的英文短句会成为 URL:
---
title: '文章标题'
description: '一句话摘要,会出现在列表页和搜索结果里'
pubDate: '2026-10-07'
tags: ['astro', 'tutorial']
draft: false
---
正文从这里开始。
draft: true 的文章只在本地开发时可见,不会进入构建产物——想写一半先存着就靠它。
本地预览
npm install
npm run dev # http://localhost:4321
npm run build # 产出 dist/ 静态文件
npm run preview # 用本地服务器预览构建结果
保存即热更新,不用等构建。
发布到 Cloudflare Pages
- 把项目推到一个 GitHub 仓库(public 或 private 都行);
- 打开 Cloudflare Dashboard → Workers & Pages → Create → Pages → 连接该仓库;
- 构建配置填:
Framework preset: Astro
Build command: npm run build
Build output: dist
- 保存。之后每次
git push,Cloudflare 自动构建并发布,历史版本可一键回滚。
域名绑定在 Pages 项目的 Custom domains 里加一条 CNAME 即可,证书自动签发。
注意:站点域名有两处要改成一致——
astro.config.mjs里的site和src/consts.ts里的SITE_URL。它们决定 canonical、sitemap 和 RSS 里的绝对链接,写错了会影响收录。
顺手配上的几件事
- RSS:
/rss.xml自动生成,读者用任意阅读器订阅; - 站点地图:
/sitemap-index.xml,提交给搜索引擎; - 评论:giscus,基于 GitHub Discussions,零后端(需在设置里显式打开);
- 统计:Cloudflare Web Analytics 免费且不需要加 cookie 横幅。
一个容易踩的坑
如果你像我一样习惯在笔记软件里写,注意双链语法 [[...]] 静态生成器不认,标准 Markdown 链接才认。图片也别直接引用笔记库里的绝对路径,要复制到 src/assets/ 再相对引用。
发布前我会跑一次 npm run build:构建通过基本等于“没有断链和语法错误”,比在浏览器里点一遍可靠得多。