从本地网页到全球上线:Codex + GitHub + Cloudflare 部署实战
你已经用 AI 做出了一个网页应用,在自己电脑上访问 http://localhost:5173 一切正常。
然后你把这个地址发给朋友,对方却打不开。
这不是代码坏了。localhost 的意思就是“这台电脑自己”,它只在你的开发环境里存在。想让上海、东京、伦敦或纽约的用户都能打开,你还要完成一次部署:把可发布的网页文件交给一台长期在线、拥有公网地址的服务。
这篇文章带你完成第一次真实上线:
Codex 负责检查、修改、构建和验证;GitHub 负责保存代码与触发变更;Cloudflare Pages 负责构建、发布并从全球网络提供访问。
我们会使用一个 Vite 静态网页作为贯穿案例。React、Vue、Svelte 等 Vite 项目基本都能照做;普通 HTML 网站和 Hugo 文档站只需替换构建命令与输出目录。
完成后,你会得到:
- 一个 GitHub 代码仓库;
- 一个形如
https://你的项目.pages.dev的公开 HTTPS 地址; - 每次提交代码后自动部署的流水线;
- 每个功能分支或 PR 对应的预览地址;
- 一套让 Codex 帮你排查部署故障的提示词。
一、先建立正确模型:三个工具不是在做同一件事
把部署想象成寄一本书:
| 角色 | 类比 | 在本教程中的职责 | 关键产物 |
|---|---|---|---|
| Codex | 编辑与质检 | 读项目、改代码、执行构建、检查结果 | 可成功构建的源码 |
| GitHub | 版本仓库 | 保存提交、管理分支与 PR、通知 Cloudflare | 可追踪的 Git 版本 |
| Cloudflare Pages | 印刷与发行 | 拉取源码、执行构建、部署静态资源、提供 HTTPS | 全球可访问 URL |
最容易产生的误区是:“我装了 GitHub 和 Cloudflare 插件,Codex 就会自动替我上线。”
实际上,插件不等于账号权限。OpenAI 官方说明,插件可以包含技能、连接器或 MCP 工具;需要外部服务时,仍要连接并授权那个服务。GitHub 插件可以帮助 Codex 按正确流程处理仓库和 PR;Cloudflare 插件可以让 Codex依据当前平台规范选择 Pages、Workers 或 Wrangler 工作流。真正对外写入时,GitHub 和 Cloudflare 各自的登录、仓库访问范围与账号权限仍然生效。
这条边界不是麻烦,而是安全带:即使 AI 理解错了目标,也不应天然拥有你所有仓库和生产环境的权限。
二、这次选择 Pages,什么时候才需要 Workers?
Cloudflare 有很多产品,新手最容易在这一步迷路。
先看你的 npm run build 最终产出了什么:
- 如果得到
dist/、build/或public/目录,里面是 HTML、CSS、JavaScript、图片等静态文件,优先使用 Cloudflare Pages; - 如果应用必须在服务端执行代码、读取数据库、保护 API 密钥或处理后端接口,需要进一步考虑 Pages Functions 或 Cloudflare Workers;
- 如果项目依赖常驻进程、本地磁盘、特定服务器软件,不能直接假设能部署到 Pages,需要先评估运行时。
本教程选择 Pages,因为它把第一次部署缩成一条非常清楚的链路:
GitHub 分支 → Cloudflare 拉取代码 → 执行构建 → 发布输出目录 → HTTPS 地址Cloudflare 官方文档明确支持将 Pages 项目连接到 GitHub 或 GitLab;分支有新推送时会自动部署,并可为分支和 PR 生成预览地址。
三、开始前准备:四样东西就够了
你需要:
- 安装并登录 ChatGPT 桌面应用,进入 Codex,打开网页项目所在文件夹;
- 一个 GitHub 账号;
- 一个 Cloudflare 账号;
- 项目在本地可以启动,至少能看到页面。
建议再准备:
- 安装 Node.js 的当前 LTS 版本;
- 安装 Git;
- 如果准备走命令行,安装并登录 GitHub CLI
gh; - 项目根目录存在
package.json。
安装 GitHub 与 Cloudflare 插件
在 ChatGPT 桌面应用的 Codex 页面打开 Plugins:
- 搜索并安装 GitHub 插件;
- 搜索并安装 Cloudflare 插件;
- GitHub 插件提示连接外部服务时完成授权;
- GitHub 仓库权限优先选择“仅指定仓库”;
- 安装后新建一个 Codex 任务,让新任务加载插件提供的技能与工具。
如果使用 Codex CLI,可以运行 /plugins 打开插件浏览器;安装完成后也应新开一个会话。
Cloudflare 插件当前主要为 Codex 提供面向 Cloudflare 的专业工作流和最新规范。Cloudflare Dashboard 或 Wrangler 登录,才是执行部署的账号通道。
四、第 1 步:先让 Codex 做“部署体检”
不要一上来就说“帮我部署”。先让 Codex 在只读检查后给出事实。
把下面这段直接发给 Codex:
请检查当前网页项目是否适合部署到 Cloudflare Pages,暂时不要修改文件。
请给我:
1. 使用的框架和包管理器;
2. 本地启动命令、生产构建命令;
3. 构建输出目录;
4. 是否依赖服务端运行时、数据库或私密环境变量;
5. 是否存在不该提交到 GitHub 的文件;
6. 部署前必须修复的问题;
7. 最后给出 Pages、Workers 或其他方案的选择结论和理由。你希望得到的答案类似:
框架:React + Vite
包管理器:npm(存在 package-lock.json)
构建命令:npm run build
输出目录:dist
服务端依赖:无
私密变量:无
建议:Cloudflare Pages,使用 Git 集成如果 Codex 说它“不确定”,让它指出对应文件和行,不要让它靠项目名字猜。
五、第 2 步:让生产构建先在本地通过
开发服务器能打开,不代表生产构建一定成功。开发模式可能容忍警告、使用本地代理,或没有暴露大小写路径问题。
在项目根目录执行:
npm install
npm run build成功后,Vite 项目通常会生成 dist/。再执行:
npm run preview打开终端显示的预览地址,至少检查:
- 首页能打开;
- CSS、字体和图片正常;
- 主要按钮能点击;
- 刷新页面后仍然正常;
- 浏览器控制台没有阻断功能的红色错误;
- 手机宽度下没有明显溢出。
可以把执行权交给 Codex,但验收标准要说清楚:
请安装依赖并执行生产构建。若失败,先解释根因再修复;不要删除功能来绕过错误。
构建成功后启动生产预览,检查首页、静态资源、主要交互和浏览器控制台。
最后报告实际执行的命令、构建输出目录、验证证据和仍未覆盖的风险。把运行时版本写进项目
“我的电脑能构建,Cloudflare 不能”常常是 Node.js 版本不同造成的。建议在 package.json 中声明版本范围:
{
"engines": {
"node": ">=20 <23"
}
}也可以在根目录加入 .node-version 或 .nvmrc。不要盲目照抄版本;先让 Codex根据项目依赖和你本地验证通过的版本给出建议。Cloudflare Pages 的构建镜像支持通过项目文件或环境变量指定工具版本。
六、第 3 步:在推送前做一次秘密扫描
GitHub 官方明确警告:不要提交或推送密码、API Key 等敏感信息。
检查 .gitignore 至少包含:
node_modules/
dist/
.env
.env.*
!.env.example
.DS_Store然后让 Codex 检查:
请检查 git status、.gitignore 和待提交差异,重点寻找 API Key、Token、密码、私钥、数据库地址和真实 .env 文件。
只报告发现,不要提交或推送。若发现疑似秘密,告诉我文件位置和安全的替代方案,但不要在回复中完整输出秘密值。请特别记住两个规则:
VITE_开头的变量会进入浏览器构建产物,不能用来藏秘密;- 一旦秘密已经推到远端,删除文件还不够,应立即在服务端撤销并轮换该秘密。
静态网页里可以放公开 API 地址、公开分析 ID,但数据库密码、支付私钥、Cloudflare API Token 必须留在服务端或平台的秘密配置中。
七、第 4 步:把本地项目放到 GitHub
推荐路径:让 GitHub 插件协助发布
如果项目已经关联 GitHub 远端,可以对 Codex 说:
使用 GitHub 插件协助发布当前网页项目。
要求:
1. 先运行 git status 并检查差异,不能提交无关文件;
2. 确认构建通过后再继续;
3. 如果当前在 main,新建 feature/first-cloudflare-deploy 分支;
4. 只暂存本次部署准备相关文件;
5. 提交信息使用 chore: prepare Cloudflare Pages deployment;
6. 推送分支并创建草稿 PR;
7. 最后报告分支、提交、PR 地址和验证结果。为什么默认草稿 PR,而不是直接把所有东西推到 main?因为 PR 给你留下一个清楚的审查入口,Cloudflare 连接 GitHub 后还能为它生成独立预览地址。
GitHub 插件的发布工作流会先确认范围,再使用本地 Git 创建分支、暂存、提交与推送,并优先通过 GitHub 连接器创建草稿 PR。这个设计能减少“把工作区里无关改动一起提交”的风险。
兜底路径:纯命令行发布
如果项目还不是 Git 仓库:
git init -b main
git add .
git commit -m "Initial commit"然后在 GitHub 创建一个空仓库。为避免历史冲突,不要同时初始化 README、License 或 .gitignore。复制远端地址后执行:
git remote add origin https://github.com/YOUR_NAME/YOUR_REPO.git
git remote -v
git push -u origin main也可以使用 GitHub CLI 一步创建并推送:
gh auth status
gh repo create --source=. --private --remote=origin --push第一次练习建议先用私有仓库。Cloudflare Git 集成可以在你授权后读取选中的私有仓库;网站是否公开访问,与仓库是否公开是两件事。
八、第 5 步:在 Cloudflare Pages 连接 GitHub
现在进入 Cloudflare Dashboard:
- 打开 Workers & Pages;
- 选择创建应用,再选择 Pages 与 Connect to Git;
- 连接 GitHub;首次连接会要求安装并授权 Cloudflare Workers & Pages GitHub App;
- 只授权本次需要部署的仓库;
- 选择仓库与生产分支,通常是
main; - 填写构建配置;
- 保存并部署。
Vite 项目的典型构建配置
| 配置项 | 填写内容 |
|---|---|
| Framework preset | Vite(能正确识别时) |
| Production branch | main |
| Build command | npm run build |
| Build output directory | dist |
| Root directory | /,除非应用在 monorepo 子目录 |
Cloudflare Pages 官方构建配置表中,React(Vite)的典型组合就是 npm run build 与 dist。但最终以你本地真实产物为准,不要因为界面有预设就跳过检查。
其他常见项目:
| 项目类型 | 常见构建命令 | 常见输出目录 |
|---|---|---|
| 纯 HTML / CSS / JS | 留空 | 包含 index.html 的目录 |
| Vite | npm run build | dist |
| Create React App | npm run build | build |
| Hugo | hugo | public |
如果项目在 apps/web/,Root directory 应设置为该子目录;否则 Cloudflare 会在错误位置寻找 package.json。
第一次构建时,你真正要看什么?
不要只盯着最后一个红色错误。按顺序检查日志:
- Cloudflare 拉取的是哪个仓库、分支和提交;
- 当前工作目录是否正确;
- 使用了什么 Node 与包管理器版本;
- 安装依赖是否成功;
- 构建命令是否与本地一致;
- 输出目录是否真实存在;
- 最终部署 URL 是什么。
成功后,你会得到:
https://your-project.pages.dev这已经是一个公开的 HTTPS 网站。把它发给手机或另一台电脑,不需要连接你的本地网络。
九、第 6 步:不要看到“Success”就结束
部署成功只代表流水线完成,不代表产品可用。
用生产地址做一轮独立验收:
[ ] 无痕窗口可以打开
[ ] 首页状态码为 200
[ ] CSS、图片、字体没有 404
[ ] 核心按钮和表单可用
[ ] 手机尺寸布局正常
[ ] 直接打开 /about、/dashboard 等深层地址可用
[ ] 在深层地址刷新页面仍可用
[ ] Console 没有阻断功能的错误
[ ] Network 没有失败的 API 或静态资源请求
[ ] 页面中没有出现测试数据、密钥或调试信息你也可以让 Codex 使用浏览器检查,但要给它生产 URL 和验收项:
请打开这个 Cloudflare Pages 生产地址并做上线验收:<URL>。
检查桌面和手机视口、首页与深层路由刷新、主要交互、Console 和 Network。
不要修改代码。请按“通过 / 失败 / 未覆盖”输出证据,并区分代码问题与部署配置问题。十、第 7 步:让后续每次修改都安全上线
Cloudflare Pages 的 Git 集成会在分支推送后自动构建。GitHub PR 来自同一仓库时,Pages 会生成唯一预览 URL,并随着该分支的新提交更新;main 的提交则更新生产地址。
因此,下一次改功能时使用这条循环:
新建功能分支
↓
让 Codex 实现并在本地构建
↓
推送分支并创建草稿 PR
↓
打开 Cloudflare 预览 URL 验收
↓
通过后合并到 main
↓
Cloudflare 自动更新生产地址这比“每改一次就手动上传一个压缩包”可靠得多:代码版本、部署记录和线上结果能够互相对应,出问题也能定位到具体提交。
注意:Pages 的预览部署默认是公开 URL。包含未发布功能或内部数据时,应使用 Cloudflare Access 限制预览访问,不要把“地址很难猜”当作权限控制。
十一、可选:不用 Git 集成,直接用 Wrangler 部署
如果你只是临时演示,或者需要从自己的 CI 发布,可以使用 Cloudflare 官方 CLI Wrangler:
npm install -D wrangler@latest
npx wrangler --version
npx wrangler login
npx wrangler whoami
npx wrangler pages project create my-first-site
npm run build
npx wrangler pages deploy ./dist --project-name my-first-site这条路径的优势是自动化程度高,缺点是新手更容易混淆“本地构建成功”和“线上配置正确”。第一次上线优先推荐 Git 集成,因为它能自然形成提交、预览与生产的闭环。
还要注意:Pages 项目创建时选择 Git 集成还是 Direct Upload 会影响后续工作流。Cloudflare 官方说明,Git 集成项目不能直接切换成 Direct Upload 类型;虽然可以关闭自动部署后使用 Wrangler 向现有项目发布,但应在创建项目前先决定主路径。
十二、给网站绑定自己的域名
pages.dev 已经可以供全世界访问。拥有域名后,再做品牌化:
- 进入 Pages 项目;
- 打开 Custom domains;
- 选择 Set up a domain;
- 输入
www.example.com或example.com; - 按提示完成 DNS 配置并等待证书生效。
Cloudflare 官方规则是:
- 根域名
example.com需要作为 Cloudflare Zone 并把域名服务器指向 Cloudflare; - 子域名
www.example.com可以通过 CNAME 指向<项目>.pages.dev; - 不能只手工添加 CNAME 而跳过 Pages 中的“添加自定义域名”步骤,否则可能出现解析错误。
上线后同时检查:
curl -I https://example.com
curl -I https://your-project.pages.dev确认 HTTPS 正常,并决定是否把 pages.dev 重定向到主域名,避免用户看到两个生产地址。
十三、六类高频故障,按层排查
1. Cloudflare 找不到仓库
现象:仓库不出现在选择列表,或提示无权访问。
优先检查:
- Cloudflare Workers & Pages GitHub App 是否安装到正确个人账号或组织;
- GitHub 的 Repository access 是否包含目标仓库;
- 你在组织中是否有安装 GitHub App 的权限;
- 仓库是否被转移、改名或删除。
不要先改代码,因为这属于授权层问题。
2. 依赖安装失败
现象:npm install 或锁文件阶段报错。
优先检查:
- 仓库里是否提交了
package-lock.json、pnpm-lock.yaml或yarn.lock; - Cloudflare 使用的包管理器是否与本地一致;
- Node 版本是否兼容;
- 依赖是否来自需要认证的私有源。
3. 构建成功,但提示找不到输出目录
现象:日志中构建通过,发布阶段说 dist 不存在。
原因通常是:
- 填错 Build output directory;
- monorepo Root directory 错了;
- 框架实际输出到
build或其他目录; - 构建脚本只在某个环境变量存在时才产出文件。
让 Codex 对比本地目录树与 Cloudflare 配置,不要创建一个空 dist 来“消除错误”。
4. 首页能开,刷新子路由 404
先判断项目类型:
- 多页静态站应该为每个路径生成对应 HTML;
- SPA 需要将导航请求回退到
index.html。
Cloudflare Pages 在没有顶层 404.html 时会将项目视作 SPA 并提供相应回退行为。需要显式规则时,可以在会被复制到构建产物的 public/_redirects 中配置:
/* /index.html 200但不要给 Hugo 等真正的多页站点乱加这条规则;它可能掩盖缺失页面,并带来重复内容问题。
5. 页面打开后白屏,资源 404
常见原因是资源路径写成了只适合某个子目录的绝对路径,或 Vite base 配置错误。
检查浏览器 Network 中第一个失败资源,再让 Codex追踪它是由哪个构建配置产生的。不要靠“把所有路径都改成相对路径”碰运气。
6. 本地正常,线上 API 失败
优先检查:
- 本地开发代理是否只写在 Vite dev server 配置里;
- 生产环境 API Base URL 是否缺失;
- API 是否允许生产域名跨域访问;
- HTTPS 页面是否请求了 HTTP API;
- 你是否误把服务端密钥打进浏览器。
这是运行时请求层问题,不一定是 Cloudflare 构建问题。
十四、让 Codex 真正好用的四段提示词
提示词 1:部署准备
目标:让当前网页项目通过 GitHub 部署到 Cloudflare Pages。
先只读检查项目,识别框架、包管理器、构建命令、输出目录、运行时依赖和秘密风险。
给出最小改动计划,等我确认后再修改。
约束:不更换框架,不删除功能,不提交 .env,不改无关文件。
验收:本地生产构建通过,输出目录明确,部署配置有官方依据。提示词 2:GitHub 发布
请使用 GitHub 插件发布这次部署准备改动。
先检查 git status 和完整 diff;工作区若有无关改动必须停下来说明。
创建独立分支,只暂存目标文件,运行相关检查,提交并推送,最后创建草稿 PR。
不要强推,不要提交秘密,不要直接合并 main。提示词 3:部署失败排查
这是 Cloudflare Pages 构建日志:<粘贴日志或提供页面>
请先判断失败发生在拉取、安装、构建、产物、部署还是运行时层。
找出日志中最早的关键错误,并与本地 package.json、锁文件和构建输出核对。
先解释根因和最小修复,不要为了让流水线变绿而跳过测试或吞掉错误。
修复后重新运行本地构建,并列出仍需在 Cloudflare Dashboard 手工确认的配置。提示词 4:上线验收
请对生产 URL <URL> 做只读上线验收。
检查:HTTP 状态、静态资源、桌面与手机布局、核心交互、深层路由刷新、Console、Network 和敏感信息暴露。
输出表格:检查项、结果、证据、严重度、建议动作。
不要只说“页面能打开”,也不要未经我同意修改生产配置。十五、今天就能完成的上线检查表
本地
- Codex 已识别真实框架、构建命令和输出目录;
-
npm run build成功; - 生产预览通过;
- Node 与包管理器版本可复现;
-
.gitignore已覆盖依赖、产物与.env; - 没有秘密进入待提交差异。
GitHub
- 仓库远端正确;
- 提交只包含本次范围;
- 分支已推送;
- 草稿 PR 能看到完整差异;
- Cloudflare GitHub App 只拥有必要仓库权限。
Cloudflare
- 生产分支正确;
- Root directory 正确;
- Build command 与本地一致;
- Output directory 与真实产物一致;
- 首次构建日志无隐藏警告;
-
pages.dev地址在其他网络和设备可访问。
上线后
- 首页、静态资源、交互与深层路由通过;
- Console 与 Network 没有关键错误;
- 预览地址和生产地址没有混淆;
- 自定义域名 HTTPS 正常;
- 团队知道如何从新分支发起下一次部署。
结语:上线不是最后一条命令,而是一条可重复的证据链
第一次部署最重要的收获,不是多了一个网址,而是理解了这条链路:
本地构建证明源码能产出 → GitHub 提交证明版本可追踪 → Cloudflare 日志证明部署过程完成 → 生产验收证明真实用户能用。
Codex 的价值,是帮你读懂项目、执行重复步骤、分析证据并缩短故障定位时间;GitHub 与 Cloudflare 的价值,是把一次偶然成功变成可以重复、预览、审查和回退的交付流程。
当你能独立走完这条闭环,你就不再只是“让 AI 生成了一个网页”,而是完成了一个真正对外提供服务的软件交付。