使用 Astro 构建并部署个人博客到 GitHub Pages 全流程指南
Astro 在众多静态网站生成器(如 Hexo、Hugo、11ty)中脱颖而出,原因清晰:
- 极快的加载速度:Astro 默认采用静态渲染,生成纯 HTML,没有多余前端负担。用户打开博客会非常迅速。
- 框架无关且兼容多框架:不局限于某个框架。可以在同一项目中混用 React、Vue、Svelte 等组件。如果你已熟悉这些框架,迁移成本很低。
- 原生支持 Markdown 和 MDX:在清晰的 Markdown 中可选地嵌入 JSX 组件进行动态内容。
- 部署简洁,生态活跃:社区非常活跃,文档完善,官方提供多种部署方案。维护成本低。
Astro 更现代化、更易上手,也更符合当前前端发展趋势。如果你在考虑博客的新技术栈,它值得一试。
创建 Astro 博客项目
确保已安装 Node.js ≥ 18。使用官方脚手架创建项目:
npm create astro@latest
Astro 会启动交互式向导引导你选择模板。选择 Blog 模板以快速获得示例文章和布局框架。脚手架会自动安装依赖;如果没有,进入项目目录后运行 npm install。
启动开发服务器:
npm run dev
Astro 默认在端口 4321 运行。在浏览器中打开 http://localhost:4321 查看本地预览。你应该立即看到一个可用的博客。
注意:如果 4321 端口被占用,Astro 会尝试下一个可用端口。终端显示实际地址——以终端输出为准。
Astro 项目现在运行中。接下来是自定义。
自定义页面和内容
博客模板包括基本页面和示例内容。常见的自定义包括:
- 首页:编辑
src/pages/index.astro以改变首页显示内容。 - 关于页面:编辑
src/pages/about.astro(或按第 3.2 节重命名)以个性化你的简介。 - 博客文章:在
src/content/blog/中添加 Markdown 或 MDX 文件。Astro 在构建时将它们转换为静态页面。
文章使用 YAML 前置信息表示元数据(标题、日期、标签),然后是 Markdown 内容。参考已有示例作为你自己文章的模板。
关于页面示例
<Layout
title="About Me" <!-- 页面标题,将会显示在页面头部或标签页标题 -->
description="Software Engineer & AI Explorer" <!-- 页面描述,有利于SEO -->
pubDate="2025-04-02" <!-- 发布日期 -->
heroImage="/blog-placeholder-about.jpg" <!-- 页眉背景图(从 public/ 文件夹引用) -->
>
<p>
Hi! I’m Yuxu Ge, a software engineer and AI enthusiast with 10+ years of backend experience.
I'm currently pursuing an MSc in AI, exploring LLMs, RAG, agents and virtual intelligence.
</p>
</Layout>
这个 Astro 组件使用博客模板提供的 <Layout> 辅助,传入标题、描述、日期和英雄图像。更新文本,将"Yuxu Ge"改为你的名字,并让 heroImage 指向你在 public/ 中的自己的图像文件。Astro 将 /public 映射到网站根目录,所以如果该文件在公共文件夹中,/blog-placeholder-about.jpg 就能工作。
生成 /about.html 而非 /about/index.html
默认情况下,Astro 生成目录形式的页面:about.astro 变成 dist/about/index.html(访问为 /about/)。如果你更喜欢文件形式的路径如 /about.html,重命名文件:
src/pages/about.html.astro
文件名中的 .html 告诉 Astro 输出独立的 HTML 文件而不是目录结构。两种方式都有效;这只是 URL 风格偏好。
自定义完内容后,正确处理图像——这是部署中的常见失败点。
在 Markdown 中正确处理图像
技术博客需要图像。在 Astro 中,不正确的图像路径导致常见问题:图像在本地显示但部署后消失。修复很简单:
- 将图像放在
public/:例如,public/images/blog/my-post/image.jpg。 - 在 Markdown 中用绝对路径引用:

前导 / 表示"从网站根目录",这映射到 public/。Astro 将 public/ 中的所有内容原样打包到 dist/ 中,所以你的图像在开发和生产中都显示。
不要将图像与 src/content/ 中的 Markdown 文件混在一起。Astro 忽略那里的二进制文件,所以构建输出不会包含它们——本地编辑器预览显示图像,但浏览器得到 404。把 public/ 想象成你仔细打包的行李;src/content/ 是你留在身后的东西。
学到的教训:我曾部署一篇文章,只发现所有图像损坏。修复:将图像移到
public/并使用根相对路径。它立即解决了问题。
静态资源放在 public/。这单一规则防止路径问题。
使用 gh-pages 部署到 GitHub Pages
通过在本地构建并将 dist/ 推送到 gh-pages 分支,将你生成的静态站点部署到 GitHub Pages。方法如下:
安装部署工具:
npm install --save-dev gh-pages该包提供 CLI 工具以将文件发布到你的仓库的
gh-pages分支。配置
astro.config.mjs:设置base路径,使 Astro 知道站点将在何处。
对于名为 virtual-velocity 的仓库,添加:
import { defineConfig } from 'astro/config';
export default defineConfig({
base: '/virtual-velocity/', // 基础路径:替换为你的仓库名,加前后斜杠
});
base 属性告诉 Astro 部署路径。如果你的仓库是 virtual-velocity,站点位于 https://用户名.github.io/virtual-velocity/,所以 base 必须是 /virtual-velocity/。此路径必须与你的仓库名称匹配,否则 CSS、JavaScript 和图像在部署后将 404,你的站点看起来会被破坏。我在第一次部署时跳过了这一步——结果是一个被搞乱的页面。添加配置修复了它。
对于用户级仓库如 username.github.io(在你的根域名部署),要么跳过 base,要么将其设为 /(默认值)。
- 在
package.json中添加部署脚本:
// package.json 部分内容
"scripts": {
"deploy": "astro build && gh-pages -d dist --branch gh-pages" // 构建并推送到gh-pages分支
}
此脚本在一步中构建站点并将 dist/ 推送到远程 gh-pages 分支。你可以拆分这些命令,但单一脚本更方便。
- 运行部署:
npm run deploy
脚本构建并推送到你的仓库。首次运行时,它可能会要求输入 GitHub 凭证。GitHub 不再接受密码认证;你需要个人访问令牌或 SSH 密钥(第 7 部分涵盖)。命令成功后,你的仓库的 gh-pages 分支被更新。
- 验证 GitHub Pages 部署:登入 GitHub,打开你的仓库,进入 Settings → Pages。如果存在,GitHub 通常自动使用
gh-pages分支。如果没有,手动将源设为该分支。几秒后,你的站点应该在(对于项目仓库)上线:
https://<你的 GitHub 用户名>.github.io/<你的仓库名>/
将 username 和 repo-name 替换为你自己的。对于示例 virtual-velocity 仓库,访问 https://yourname.github.io/virtual-velocity/ 查看你部署的博客。
注意:如果
gh-pages报告"分支已存在",添加--force覆盖:gh-pages -d dist --branch gh-pages --force。注意强制推送会覆盖先前的分支历史。
你的 Astro 博客现在在 GitHub Pages 上。更新只需一个命令:npm run deploy。
常见问题和解决方案
部署通常能工作,但这是我遇到过的问题及修复方法:
- 缺失
sharp模块:如果你看到Error: Cannot find module 'sharp',运行npm install sharp。或者使用 Astro 的 Squoosh 图像处理(基于 WebAssembly,无本地二进制依赖)。 - 图像在本地工作但部署后 404:图像在错误的位置。把它们放在
public/中并用以/开头的绝对路径引用。只有public/中的文件被打包到已发布站点中。 - 构建输出
/about/index.html而不是/about.html:这是 Astro 的默认行为。将页面文件重命名为about.html.astro(见第 3.2 节)以生成单个 HTML 文件。 gh-pages报告"远程分支已存在":在部署命令中添加--force以覆盖分支。注意强制推送会丢弃先前历史,所以谨慎使用。- SSH 连接错误(端口 22 被阻挡):某些网络(公司、校园)阻止端口 22。如果你的本地仓库使用 SSH,部署会失败。切换到 HTTPS:
git remote set-url origin https://github.com/yourname/yourrepo.git。HTTPS 使用端口 443,很少被阻止。 - GitHub 拒绝你的密码:GitHub 禁用了基于密码的 Git 认证。改用个人访问令牌,或设置 SSH 密钥(见第 7 部分)。
关于认证的最后一点是关键的。没有正确的凭证,代码不会推送。接下来让我们涵盖认证。
GitHub 认证设置(必要的)
自 2021 年末起,GitHub 要求令牌或 SSH 密钥用于 git push。密码认证不再工作。你有两个选择:
个人访问令牌(PAT):在 GitHub 的开发者设置中生成令牌(选择经典类型,启用
repo范围)。复制它并在推送时提示时粘贴。像对待密码一样对待令牌——安全保存它,永远不要提交到仓库。如果泄露,立即在 GitHub 设置中撤销它。提示:把令牌想象成命令行访问的"临时护照"。在 GitHub 设置 中生成它,始终保持私密。
SSH 密钥:如果你已在本地创建了 SSH 密钥对并将公钥添加到你的 GitHub 账户,使用 SSH 进行无密码认证:
git remote set-url origin [email protected]:yourname/yourrepo.git
将 yourname/yourrepo 替换为你的 GitHub 用户名和仓库名。这将远程 URL 从 HTTPS 改为 SSH 格式。推送命令现在通过 SSH 认证(假设端口 22 未被阻止且你已将公钥添加到 GitHub)。如果你还没有生成 SSH 密钥,请参考 GitHub 的文档。
对大多数独立开发者来说,令牌认证更简单:生成一次,用于所有部署。SSH 对经常使用 Git 且想要零密码工作流的人更好。不管怎样,在部署前设置一个,否则你会在认证步骤卡住。
自定义域名设置(可选)
完成上述步骤后,你的博客在 GitHub 的默认域名上(例如 https://yourname.github.io/yourrepo/)。要使用你自己的域名如 blog.geyuxu.com,按这些步骤:
在 GitHub 中设置自定义域名:打开你的仓库的 Settings → Pages。找到"自定义域名"字段,输入你的域名(例如
blog.geyuxu.com),并保存。检查"强制 HTTPS"以自动将 HTTP 流量重定向到 HTTPS。在
public/中添加 CNAME 文件:在你的public/文件夹中创建一个名为 CNAME 的纯文本文件(无扩展名),单行:blog.geyuxu.com
保存并提交此文件。当 Astro 构建时,它在输出中包括 CNAME。此文件告诉 GitHub Pages 使用哪个域。
警告:不要在 CNAME 文件中包含
http://或https://,并移除任何尾部空白。GitHub 对格式很严格。
配置 DNS:登入你的域注册商并添加 DNS 记录:
- 类型:CNAME
- 名称:子域前缀,例如
blog.geyuxu.com的blog(根域留空或使用@,但根域也需要 A 记录——见 GitHub 的文档) - 值:你的 GitHub Pages 地址,例如
yourname.github.io - TTL:默认或自动
示例:对于
blog.geyuxu.com和 GitHub 用户geyuxu,创建 CNAME 记录指向blog到geyuxu.github.io。测试:DNS 更改需要数分钟到数小时才能传播。一旦更新,访问你的自定义域(例如 https://blog.geyuxu.com)应该显示你的博客。
提示:
- 在首次设置后,
npm run deploy自动包括你的 CNAME 文件,所以你以后不需要手动重新配置 GitHub Pages。 - 对于根域(例如
geyuxu.com而不是子域),你需要 CNAME 记录和指向 GitHub IP 地址的 A 记录。查看 GitHub 的文档 获取当前 IP。
总结
Astro 和 GitHub Pages 结合创建一个快速、可维护、免费的个人博客。一旦设置完成,发布是单一命令:npm run deploy。进入门槛很低——专注于写作,而不是部署基础设施。
工作流很清晰:用 Astro 搭建脚手架,自定义你的内容,配置部署,排查常见问题,设置认证,并可选地添加自定义域名。每一步都是可管理的。通过遵循此指南,你会避免常见陷阱,并拥有分享你的想法在线的坚实平台。
示例 URL(部署后):
- 默认 GitHub Pages URL:https://yourname.github.io/your-repo/(将 yourname 和 your-repo 替换为你自己的)
- 自定义域名示例:你自己的域名在 DNS 中注册并按上面配置