用 Astro + Cloudflare Pages 搭一个零成本博客

· 约 3 分钟

这个站点本身就是按下面这套方案搭的。整个过程只有一笔支出:域名年费(几十到一百块)。构建、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

  1. 把项目推到一个 GitHub 仓库(public 或 private 都行);
  2. 打开 Cloudflare Dashboard → Workers & Pages → Create → Pages → 连接该仓库;
  3. 构建配置填:
Framework preset:  Astro
Build command:     npm run build
Build output:      dist
  1. 保存。之后每次 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:构建通过基本等于“没有断链和语法错误”,比在浏览器里点一遍可靠得多。