用 Claude Code、GitHub 和 Cloudflare 发布一个真正的网站(便宜又可靠)
把网站放到网上最便宜、最持久的方式其实没怎么变过:把静态文件发布到 CDN,用 Git 做版本控制,每次推送都触发构建。真正变的是谁来帮你把这些步骤串起来。现在你可以把网站描述给一个 AI 编程助手(coding agent),让它跑完整个流程,而你只需要点两个只有人类才能点的按钮。这就是我自己用来发布这个出版物的网站的技术组合——我把它写下来,你可以直接扔给你的 AI 助手,一个下午就能在你自己的域名上看到活着的网站。有意思的不是工具本身,而是分工:AI 跑完整个序列,你只负责那两个它确实做不到的步骤。
太长不看版 TL;DR
- 网站框架:Astro(静态输出)
- 源码管理:GitHub
- 托管:Cloudflare Pages
- 构建工具:pnpm
- 质量门:一个小小的 Playwright 冒烟测试
- 成本:每月约 0 美元,外加域名(大约每年 8 到 15 美元)。因为 CDN 上的静态文件不需要任何服务器运行或扩容。
- 可靠性:没有源服务器会崩溃,没有数据库会损坏。最常见的故障是你自己敲的一个拼写错误——冒烟测试正好能抓住它。
- 周一动手:装四个工具(Node、pnpm、git、GitHub CLI),然后把下面那段「给你的 AI」提示词贴给 Claude Code,回答它的问题。整个过程中唯一不能替你做的,就是在 Cloudflare 控制面板里点两下。
为什么这套方案又便宜又可靠
可靠不是靠多花钱得来的,而是来自系统的结构。一个静态站点就是一个装着 HTML、CSS 和少量 JavaScript 的文件夹。从 CDN 分发出去后,没有服务器进程需要打补丁,没有运行时崩溃,也没有数据库会损坏。你的仓库就是事实源头,GitHub 负责存着它,每次推送 Cloudflare 都会重建并发布网站。最常见搞坏它的方法是在你自己的内容里打错字——下面那个测试门会在这些错误上线前抓住它们。
分层选择
| 层 | 选择 | 原因 |
|---|---|---|
| 框架 | Astro(静态输出) | 默认输出纯粹的 HTML 和 CSS,几乎不包含 JavaScript,所以页面很快,也不需要服务器运行时。内容用仓库里的 Markdown 或 MDX 编写。 |
| 源码控制 | GitHub(私有仓库) | 免费、持久,又是 Cloudflare 监听的东西。 |
原文:
一个糟糕的改动,一条 git revert 就能撤回。Cloudflare Pages 免费版自带全球 CDN、自动 HTTPS,以及和 Git 联动的自动部署。在 CDN 上做静态托管,可以说是互联网上最靠谱的方案之一。包管理器用 pnpm——安装速度快、节省磁盘空间。npm 或 yarn 也能用。质量门控用构建检查加一个 Playwright 冒烟测试:在问题影响到用户之前,就能捕获构建失败、图片缺失和死链。另外一些同样可行的方案:如果要服务端逻辑可以用 Cloudflare Workers;如果要做单页应用,可以用 Vite + React、Svelte 或 Vue;也可以用 Netlify 或 GitHub Pages 替代 Cloudflare Pages。核心原则是相通的。本指南挑选了一条好用的默认路径,这样你的 AI 就不需要反复斟酌了。
前置条件(一次性设置,大约 15 分钟)
三个免费账号:一个 GitHub 账号、一个 Cloudflare 账号,以及如果你想用自定义域名的话还需要一个域名(Cloudflare Registrar 按成本价卖域名,这是最便宜且诚实的选项)。你可以跳过域名,直接用免费的 *.pages.dev 子域名。
你机器上需要装四个工具:Node.js LTS(版本 20 或更新)、pnpm(npm install -g pnpm)、Git,以及 GitHub CLI(gh,然后执行 gh auth login 一次,这样你的 AI 代理就能自动创建仓库,不用你手动点网页了)。外加你选用的 AI 编程代理。
验证它们安装成功:
node --version # 版本 v20 或以上
pnpm --version
git --version
gh auth status # 应该显示 "Logged in"
喂给 AI 的指令
一旦前置条件准备好,就把下面这段代码块粘贴给你的 AI 代理。(记得先替换掉括号里的值。)
I want to create and deploy a website. Use this stack and follow it exactly:
用 Claude Code、GitHub 和 Cloudflare 发布一个真实网站(便宜又靠谱)
- 框架:Astro(输出为静态站点)
- 源码仓库:一个名为
[my-site]的新私有 GitHub 仓库 - 托管:Cloudflare Pages,推送到 main 分支时自动部署
- 包管理器:pnpm
- 自定义域名(可选):
[yourname.com]
网站描述:用一两句话说明这个网站是做什么的、给谁用的。
按以下步骤操作:
- 用 pnpm 搭建一个最小的 Astro 站点,本地运行并确认构建成功。
- 初始化 git,用
ghCLI 创建私有 GitHub 仓库,然后推送。 - 添加发布门禁:一个
pnpm build检查,加上一个最小化的 Playwright 冒烟测试——加载首页、检查标题、验证每张<img>是否没有 404。配置好,确保每次推送前都能运行。 - 给我准确的 Cloudflare Pages 设置(构建命令、输出目录、框架预设),以及自定义域名的 DNS 操作步骤。这些需要你在 Cloudflare 控制台里点选,我无法代劳。
- 写一份简短的 README,包含本地开发命令、部署流程和注意事项清单。
一切从简,确保能用。不要加我没要的功能。每完成一步,告诉我你做了什么,接下来我需要做什么。唯一一件你的 agent 不能做的事,就是在 Cloudflare 控制台里点选“连接仓库和域名”。其他所有操作它都能执行。下面的步骤就是你 agent 会执行的,也是你需要点击的。
步骤 1. 搭建并确认构建成功
pnpm create astro@latest my-site
# 选择 “minimal” 或 “blog” starter,TypeScript 选 “Strict”,安装依赖
cd my-site
pnpm dev # 打开本地 URL,确认页面正常加载
pnpm build # 生成静态站点到 ./dist 目录
pnpm preview # 用与线上完全一样的方式提供 ./dist 目录
如果 pnpm build 失败,先解决再继续。本地构建通过,是 Cloudflare 能正常部署的前提。
步骤 2. 推送到 GitHub(私有仓库)
git init
用 Claude Code、GitHub 和 Cloudflare 发布一个真正的网站(便宜又可靠)
git add -A
git commit -m "Initial site scaffold"
gh repo create my-site --private --source=. --remote=origin --push
最后这条命令会创建私有仓库并一次性推送到远程。
3. 关联 Cloudflare Pages(需要你在界面上操作)
在 Cloudflare 控制面板中,打开 Workers 和 Pages,点击 创建 → Pages → 连接到 Git。授权 GitHub,选择你的仓库,然后配置构建参数:
- 框架预设:Astro
- 构建命令:
pnpm build - 构建输出目录:
dist - Node 版本:添加环境变量
NODE_VERSION,设为20(或更新版本),确保构建环境与本地一致。
点击 保存并部署。一两分钟后,你的站点就会出现在 my-site.pages.dev 上。之后每次向 main 分支推送代码,都会自动触发新部署。
4. 添加自定义域名(需要你在界面上操作)
在 Pages 项目中,打开 自定义域,点击 设置域名,输入你的域名。如果该域名的 DNS 已在 Cloudflare 管理,记录会自动添加。否则 Cloudflare 会给出具体的 CNAME 或 A 记录,你需要到域名注册商处添加;也可以直接将域名的 DNS 服务器切换到 Cloudflare(免费),让它统一管理 DNS。HTTPS 证书会自动配置。
5. 可靠性检查门
能部署成功,不代表网站一定正常运行。加一道简单的检查门,确保构建出错或图片缺失时不会影响访问者。
pnpm add -D @playwright/test
用 Claude Code、GitHub 和 Cloudflare 发布一个真实网站(便宜又可靠)
pnpm exec playwright install chromium
创建 tests/smoke.spec.ts:
import { test, expect } from "@playwright/test";
const BASE = process.env.SMOKE_URL || "http://localhost:4321";
test("home page loads with a title", async ({ page }) => {
await page.goto(BASE);
await expect(page).toHaveTitle(/.+/);
});
test("no broken images", async ({ page }) => {
await page.goto(BASE);
const srcs = await page.locator("img").evaluateAll(
(imgs) => imgs.map((i) => (i as HTMLImageElement).src).filter((s) => s.startsWith("http")),
);
for (const src of srcs) {
const res = await page.request.get(src);
expect(res.status(), `broken image: ${src}`).toBeLessThan(400);
}
});
每次推送前,先在本地预览中跑一遍这个冒烟测试。关键是养成习惯:构建通过 → 冒烟通过 → 再推送。
“无坏图”这个检查,我是吃过亏才加上的,所以它在我自己的项目里不是可选项。一个损毁的 <img> 不会让构建失败,页面上只是空出一块,而冒烟测试是唯一能低成本抓住这个问题的手段。
成本(说实话)
- 托管:Cloudflare Pages 免费套餐,无限静态请求和带宽,只是每月构建次数有上限——托管费用为 $0。
- 源码管理:GitHub 免费,私有仓库也是 $0。
- 域名:唯一固定开销,每年大概 $8 到 $15,具体看后缀。
- 其余一切在这个规模下都是免费的。如果以后网站需要后端,下一步是 Cloudflare Workers 加个小数据库,费用仍然很低。