系列 · 这个博客是怎么搭起来的 第 3 篇 / 共 3 篇 实践

GitHub Pages 是什么,以及这个博客是怎么部署的

用浏览器请求、Astro 构建、GitHub Actions 发布和分层排错四条链路,图解这个博客从源码到线上静态页面的真实部署原理。

作者:黄撑 更新于 2026-07-26
本文目录 6 节 · 点击展开

这个博客没有常驻后端进程。它先由 Astro 把源码构建成静态文件,再由 GitHub Actions 把构建产物发布到 GitHub Pages;读者访问时,Pages 直接返回已经生成好的 HTML、CSS、JavaScript 和图片。

DEPLOYMENT MODEL
源码不是网站,dist 产物才是 Pages 最终托管的内容。

Astro 负责“生成”,GitHub Actions 负责“自动执行”,GitHub Pages 负责“公开托管”。

Astro 构建器Actions 自动化Pages 静态托管

浏览器访问时,真正发生了什么

01 · REQUEST PATH一次访问,只是在请求已经发布好的静态文件
运行时无构建
GitHub PagesGitHub 提供的静态站点托管服务,可以从仓库内容或 Actions 产物发布 HTML、CSS 和 JavaScript 网站。GitHub 官方定义
HOSTGitHub Pages 接收apexcheng.github.io

Pages 按已经发布的站点版本查找对应文件。

RESPONSE返回静态资源HTML · CSS · JS · images

浏览器下载资源并在本地完成页面呈现。

访问时存在
静态文件浏览器渲染Pages 托管
这个项目访问时不需要
Node 常驻进程应用数据库Nginx 自建服务器每次请求现场构建
本站证据

astro.config.mjs 没有服务端 adapter;当前部署链路以 Astro 静态构建和 Pages artifact 为核心。

边界:需要登录、数据库写入或实时服务端计算时,静态 Pages 本身不能替代后端。

GitHub Pages 有用户 / 组织站点和项目站点两类。用户站点仓库使用特殊名称 <owner>.github.io,默认地址位于域名根路径;项目站点默认位于 /<repository>/ 子路径。这个差异会直接影响 Astro 的 base

Astro 怎样把文章变成可部署文件

02 · BUILD TRANSFORMATION构建把“项目结构”翻译成“浏览器能直接读取的文件”
npm run build
SOURCE · 输入仓库里的开发文件
  • src/content/posts/:Markdown / MDX 文章
  • src/pages/:页面与静态路由
  • src/components/:Astro 组件
  • src/styles/:站点样式
ASTRO BUILD读取内容生成路由编译与打包写入 dist/
ARTIFACT · 输出可公开托管的静态站点
  • index.html:入口页面
  • articles/…/index.html:文章页
  • _astro/…:编译后的 CSS / JS
  • 图片、字体、RSS 等公开资源
构建命令npm run build

package.json 当前映射为 astro build

默认输出dist/

项目没有覆盖 outDir,沿用 Astro 默认静态输出目录。

发布原则不提交 dist

远端 Action 会基于同一提交重新安装、构建并上传产物。

这一章的判断本地源码能打开,不等于部署产物能生成;npm run build 才是发布前最接近云端的一次检查。

可复制的本地构建命令:

npm run build
npm run preview

preview 用于检查刚生成的静态产物,不是生产服务器。Astro 官方部署文档也将默认构建命令写为 npm run build、默认发布目录写为 dist,可参考 Astro 部署说明

GitHub Actions 怎样完成自动发布

03 · DELIVERY PIPELINEmain 分支只触发流程,真正交付的是 build job 产出的 artifact
2 jobs
AUTOpush → main

main 收到新提交时自动触发。

MANUALworkflow_dispatch

允许从 Actions 页面手动运行。

QUEUEgroup: pages

cancel-in-progress: false,进行中的发布不被新运行取消。

BUILD JOB输入:仓库提交
1Checkoutactions/checkout@v6

把触发这次运行的仓库内容检出到 runner。

2Install + Buildwithastro/action@v6

使用 npm 安装依赖、执行 Astro 构建并准备 Pages artifact。

3Pages artifact静态构建产物

这是 build job 交给 deploy job 的发布对象。

needs: build只有 build 成功,deploy 才能开始
DEPLOY JOB输入:Pages artifact
4Deploy Pagesactions/deploy-pages@v5

把上一任务的 artifact 发布到 github-pages environment。

最小权限与发布身份
contents: readpages: writeid-token: write

分别用于读取仓库、写入 Pages 部署和使用 OIDC 身份令牌;这些字段与当前 workflow 一致。

这一章的判断构建失败时不会进入发布;发布成功也只证明 artifact 已部署,页面内容与缓存仍要单独验收。

当前仓库的真实 workflow 是 .github/workflows/deploy.yml。它与 Astro 官方 GitHub Pages 指南 的两任务结构一致;GitHub 也把 “checkout → build → upload artifact → deploy-pages” 作为自定义 Actions 发布的标准链路,见 GitHub Pages 发布源说明

site、base 和仓库名怎样共同决定地址

04 · ADDRESS MODEL先判断仓库属于哪种 Pages 站点,再决定 Astro 是否需要 base
路径最易出错
USER SITE · 当前博客仓库名匹配特殊规则apexcheng.github.io
  • site:设置完整域名
  • base:当前不配置
  • 页面和资源从根路径 / 开始
PROJECT SITE · 对照情况普通仓库作为项目站点about
  • site:仍是所属域名
  • base:通常配置为 /about
  • 内部链接必须带上项目子路径
当前 astro.config.mjs
export default defineConfig({
site: 'https://apexcheng.github.io',
devToolbar: {
  enabled: true,
},
integrations: [mdx()],
});
错误配置示例base: ‘/blog’
构建出的资源路径/blog/_astro/…
部署在根站点时CSS / JS 可能 404
边界与结论

仓库改名、改为项目站点或接入自定义域名时,都要重新核对 sitebase、Pages 设置和内部链接;不能只改其中一个。

当前“根路径部署”由本地配置和仓库命名共同支持;GitHub 仓库的 Pages Source 仍需在 Settings 中运行验证。

Astro 官方说明明确指出:项目站点通常要把仓库名配置为 base,而当仓库名符合 <username>.github.io 时可以跳过。当前项目的 src/utils/paths.ts 还保留了 withBase(),因此内部地址不会把根路径写死。

从改文章到线上验收,应该按哪条操作链

05 · OPERATOR RUNBOOK发布不是 push 结束,而是本地、Actions、线上三次验收
可复制执行
01
CONTENT修改文章或代码

正式文章位于 src/content/posts/;公开文章保持 draft: falseprivate: false

产出:源码变更
02
LOCAL GATE先测试,再构建
npm test
npm run build

测试负责已有规则,构建负责 MDX、路由和静态生成。

产出:可生成的 dist
03
VERSION只提交本次相关文件
git add src/content/posts/my-new-article.mdx
git commit -m "更新文章"

提交记录定义这次远端构建使用的源码版本。

产出:Git commit
04
TRIGGER推送 main
git push origin main

当前 workflow 监听 main;其他分支不会通过这条 push 规则自动部署。

产出:Actions run
05
REMOTE GATE检查 build 与 deploy

先确认 build job,再确认 deploy job;绿色状态来自真实运行,不从 YAML 推断。

产出:deployment URL
06
BROWSER GATE检查真实页面

至少打开首页、目标文章和一个静态资源;必要时使用无痕窗口排除缓存。

产出:线上验收
GATE A本地构建通过

证明这份源码能生成静态站点。

GATE BActions 两个 job 通过

证明远端环境完成构建与部署。

GATE C浏览器访问正确

证明路径、资源与内容对读者可用。

这一章的判断三个闸门不能互相替代:本地成功不代表远端权限正确,Actions 成功也不代表浏览器没有缓存或路径问题。

本文没有把 dist/ 加入提交命令,因为当前部署方式会在 GitHub runner 上重新构建。若将来改为分支目录发布,交付对象与操作链也必须随之调整。

部署失败时,怎样分层定位

06 · LAYERED DIAGNOSIS不要从“页面不对”直接猜原因,先找到故障发生在哪一层
5 层定位
当前故障层 已通过证据 尚未检查
L1
SOURCE源码与内容层

MDX 语法、frontmatter、import、公开状态、文件名是否正确。

证据npm test目标文件 diff
构建前错误
L2
BUILDAstro 构建层

依赖是否可安装,路由和 MDX 是否能生成,dist/ 是否完整。

证据npm run build构建日志首个错误
build job 红色
L3
DELIVERYActions 与 artifact 层

workflow 是否触发,build 是否上传 Pages artifact,deploy 是否获得所需权限。

证据Actions runbuild / deploy job
未触发或 job 失败
L4
ADDRESSPages 设置与路径层

Source 是否为 GitHub Actions,site / base 是否匹配用户站点或项目站点。

证据Settings → Pages资源请求 URL
404 或样式丢失
L5
BROWSER线上内容与缓存层

部署 URL 是否是最新运行,页面和静态资源是否返回预期版本。

证据无痕窗口直接访问文章路径
Actions 绿但页面旧
症状Actions 没有运行

先查 L3:提交是否真的 push 到 main,workflow 文件是否存在且能被 GitHub 读取。

症状build 失败

回到 L1 / L2:从日志第一个有效错误开始,不先改 Pages 设置。

症状页面开了但无样式

优先查 L4:CSS / JS 请求路径是否多了或少了 base

症状部署成功但内容旧

先查 L5,再核对 deploy 使用的 commit;不要把缓存问题误判为构建失败。

本地已能确认
  • site 指向 https://apexcheng.github.io
  • 当前没有配置 base
  • workflow 监听 main 并支持手动触发
  • build → deploy 依赖关系存在
需运行验证
  • 仓库 Pages Source 当前是否为 GitHub Actions
  • 最新 Actions run 是否成功
  • 线上站点和目标文章是否已更新
  • 桌面端与 390px 移动端是否无布局溢出
FINAL MODEL源码 → Astro 静态产物 → Pages artifact → GitHub Pages → 浏览器

排错时从左到右找证据;每通过一层,才继续检查下一层。

这套部署方式把内容生产、构建自动化和静态托管拆成了清晰的责任边界。对当前博客而言,最重要的不是记住某个 Action 版本,而是始终分清:源码在哪里、产物是什么、谁负责发布,以及失败证据来自哪一层。