把个人网站主页部署到 GitHub 上,用 GitHub Pages 对外发布,是开发者搭建个人主页最常用的方式之一。只要你有一个 GitHub 账号,就可以拥有一个形式完整、具备 HTTPS 访问能力、还能绑定自己域名的静态站点,整个过程不需要购买云服务器,也不需要维护 Nginx 或容器环境。
这篇文章会从“为什么要用 GitHub Pages”讲起,然后走一条完整路线:创建仓库、写首页、提交代码、开启 Pages、用 GitHub Actions 自动部署、再切换到 Jekyll 管理内容,最后绑定自定义域名并处理常见的部署问题。无论你是刚入门的技术爱好者,还是已经写过项目但没系统整理过个人主页的开发者,这套流程都可以直接照做。
整个方案可以拆成两条路线:
- 快速路线:本地写一个
index.html,推到 GitHub,在仓库设置里开启 Pages,几分钟后就能访问。 - 进阶路线:使用 Jekyll 模板管理内容和主题,通过 GitHub Actions 自动构建,绑定自己的域名并启用 HTTPS。
两条路线共用同一个底层机制,所以先搞清楚 GitHub Pages 是什么,后面的每一步都会顺畅很多。
1. 先搞清楚 GitHub Pages 的定位和边界
1.1 GitHub Pages 免费帮你做好的三件事
GitHub Pages 是 GitHub 提供的静态站点托管服务。它不是一个完整的云主机,它只负责“接收静态文件、生成页面、对外托管”,但它把三件很麻烦的事都替你处理了:
第一,静态文件的全球分发。你不需要自己配置 CDN,GitHub Pages 会通过自己的基础设施分发页面,访问速度整体比较稳定。
第二,HTTPS 证书。只要是 GitHub 提供的默认域名username.github.io,证书会自动生效。绑定自定义域名后,只要 DNS 配置正确,证书也可以自动签发和续期。
第三,和 Git 工作流天然集成。你每次git push都会触发新的发布,历史版本可以回滚,页面内容就是仓库里的代码和文件,管理体验和管项目源码完全一致。
1.2 什么内容适合放在 GitHub Pages 上
个人网站主页、简历页、作品集、项目介绍页、个人博客、开源项目文档站,这些都属于典型的静态站点,非常适合放在 GitHub Pages 上。
但不适合把需要后端服务的功能放在这里,比如用户登录、订单处理、数据库写入、动态接口。如果主页里要显示实时数据,正确做法是把 GitHub Pages 当作前端展示层,让页面通过 API 请求你自己的后端服务。
还需要注意,GitHub Pages 对单站大小和流量有使用限制,常见说明是发布内容不能超过 1GB,带宽也有软性限制。个人主页远达不到这个规模,但如果想用来托管大量高清图片或视频文件,就不合适了。
1.3 仓库、分支和 Pages 发布来源的关系
一个 GitHub Pages 站点通常由一个仓库驱动。对你最关键的是仓库名:
- 用户主页仓库名必须是
username.github.io,其中username是你的 GitHub 用户名。 - 项目主页仓库名可以是任意名字,发布后访问路径会变成
username.github.io/repo-name/。
发布来源有两种常见选择。一种是在仓库的 Settings -> Pages 页面里,选择“Deploy from a branch”,然后指定main分支和目录(根目录或docs目录)。另一种是选择“GitHub Actions”,通过工作流文件控制构建和发布。
对于个人主页,最省心的是把仓库命名为username.github.io,因为语义清晰、访问路径干净,而且后续绑定自定义域名时不需要处理子路径问题。
2. 环境准备与仓库初始化
2.1 本地工具清单和检查命令
在写页面之前,先把本地环境确认一遍。最基础的工具是 Git 和一个代码编辑器。
| 工具 | 用途 | 检查命令 |
|---|---|---|
| Git | 提交和推送代码 | git --version |
| 代码编辑器 | 编辑 HTML、CSS、Markdown | 任意编辑器均可 |
| Ruby(可选) | 本地运行 Jekyll | ruby -v |
| Bundler(可选) | 管理 Jekyll 依赖 | bundle -v |
如果只写纯 HTML,不需要安装 Ruby。如果要使用 Jekyll,再安装 Ruby 环境。安装完成后,先配置 Git 的用户信息,否则提交时会出现“作者信息缺失”的提示。
git config --global user.name "your-name" git config --global user.email "you@example.com"user.name会显示在提交记录里,user.email建议和 GitHub 账号绑定的邮箱保持一致,这样你的提交记录能正确关联到 GitHub 主页。
2.2 创建 GitHub 仓库并选择可见性
登录 GitHub 后,点击右上角的+,选择New repository。仓库名如果是个人主页,就填写username.github.io,这里的username必须和你的 GitHub 用户名完全一致,大小写也要准确。
可见性怎么选?个人主页内容通常没有保密需求,选择 Public 是最方便的。Public 仓库可以让 GitHub Pages 的构建和部署流程更顺畅,也方便别人看到你的主页源码,这对个人展示是有加分的。
如果因为某些原因把仓库设成了 Private,需要先确认当前 GitHub 套餐是否支持从私有仓库发布 Pages。不同时期、不同套餐的规则会有变化,不要想当然。
创建仓库时可以勾选Add a README file,也可以不勾选。为了保证后续操作干净,建议不勾选任何初始化文件,直接创建一个空仓库,然后从本地推代码。
2.3 本地初始化和第一次提交
在本地建一个和仓库同名的目录,进入目录后初始化 Git:
mkdir username.github.io cd username.github.io git init git branch -M main添加远程仓库地址。如果使用 HTTPS 方式:
git remote add origin https://github.com/username/username.github.io.git如果使用 SSH 方式:
git remote add origin git@github.com:username/username.github.io.git两种方式都可以,使用 SSH 需要先配置好 SSH Key。第一次提交时,先创建一个index.html文件,再进行提交:
git add . git commit -m "init homepage" git push -u origin main推送成功后,仓库里能看到完整的文件列表,这就是后面所有自动化操作的基础。
3. 用纯 HTML 搭建第一个可运行主页
3.1 页面骨架文件 index.html
GitHub Pages 在访问根路径时,会优先找index.html。所以第一个文件必须是这个名字,内容不需要复杂,但结构要完整。
下面是一个适合个人主页的最小页面骨架:
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>我的个人主页</title> <link rel="stylesheet" href="style.css"> </head> <body> <header> <h1>你好,我是 [你的名字]</h1> <p>前端 / 后端 / 运维 / 兴趣方向</p> </header> <main> <section> <h2>关于我</h2> <p>写一段自我介绍,突出你会什么、正在做什么、想找什么样的人合作。</p> </section> <section> <h2>项目</h2> <ul> <li><a href="https://github.com/username/project-a">项目 A 仓库</a></li> <li><a href="https://github.com/username/project-b">项目 B 仓库</a></li> </ul> </section> </main> <footer> <p><a href="mailto:you@example.com">联系我</a></p> </footer> </body> </html>这个页面包含了个人主页最核心的几个区块:头部标语、个人介绍、项目链接、联系方式。meta name="viewport"一定要保留,否则手机上访问时页面宽度会异常。
3.2 添加样式并适配手机端
纯 HTML 页面文字出来后,还需要一个style.css让页面不至于太简陋。下面的样式尽量保持简单,但已经处理好布局和移动端适配:
:root { --main-color: #2563eb; } * { box-sizing: border-box; } body { font-family: system-ui, -apple-system, "PingFang SC", "Microsoft YaHei", sans-serif; margin: 0; line-height: 1.7; color: #1f2933; } header { background: var(--main-color); color: #fff; padding: 4rem 1rem; text-align: center; } main { max-width: 760px; margin: 0 auto; padding: 2rem 1rem; } section { margin-bottom: 2.5rem; } a { color: var(--main-color); } footer { text-align: center; padding: 2rem 1rem; color: #52606d; } @media (max-width: 600px) { header { padding: 2rem 1rem; } main { padding: 1rem; } }这里使用了 CSS 变量--main-color,后续想换主题色时,只需改这一处。max-width加margin: 0 auto是让内容在大屏上保持舒适的阅读宽度,避免文字撑满整行。
3.3 用 README 和 404 页面补齐站点体验
个人主页虽然只有几个页面,但建议补上两个文件。
第一个是README.md,它不会出现在你的主页页面里,但会展示在仓库文件列表下方。可以写清楚这个仓库的结构、如何本地预览、如何部署,方便别人看代码时快速理解。
第二个是404.html。当访问者输入了错误地址,GitHub Pages 会返回默认 404 页面,但默认页面里没有回到你主页的入口。自定义一个更友好:
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>页面不存在</title> </head> <body style="text-align:center;padding-top:80px;font-family:system-ui,sans-serif;"> <h1>404</h1> <p>你访问的页面不存在,回到 <a href="/">首页</a>。</p> </body> </html>这里的/在用户主页username.github.io下没有问题。如果站点部署在项目路径下,比如username.github.io/repo/,需要把链接改成相对路径或加上baseurl,否则会跳错位置。
3.4 在仓库设置中开启 GitHub Pages
推到远程仓库后,打开仓库页面,进入 Settings -> Pages,在Build and deployment区域选择Deploy from a branch,分支选择main,目录选择/root,点击 Save。
保存后 GitHub 会开始构建。等待一两分钟,访问https://username.github.io,如果能看到刚才写的 HTML 内容,就说明第一个简单版本的个人主页已经上线了。
这个流程不需要额外安装任何依赖,适合快速验证。如果想做得更有工程感,就需要进入下一步,用 GitHub Actions 控制构建过程。
4. 用 GitHub Actions 把构建部署变成自动化流程
4.1 为什么建议用 Actions 而不是只开默认 Pages
直接选Deploy from a branch对纯 HTML 很省事,但有一个局限:你无法在发布前执行构建步骤。比如你用了 Jekyll、Hugo、React 静态导出,或者需要在发布前压缩图片、生成站点地图,GitHub 分支发布模式就满足不了了。
GitHub Actions 可以解决这个问题。它会在你git push后自动执行工作流,把构建产物上传到 Pages 并发布。这样部署流程完全由代码定义,和项目一起版本化,换电脑后不需要重新配置。
对于纯 HTML 项目,Actions 的价值更多在于“统一发布入口”。对于 Jekyll 或静态站点生成器项目,Actions 则是必须的,因为发布的是构建后的文件,不是源码本身。
4.2 Workflow 文件怎么配置
在仓库根目录创建.github/workflows/deploy.yml,写入下面的内容。这个工作流针对静态 HTML 项目:
name: Deploy static content to Pages on: push: branches: - main workflow_dispatch: permissions: contents: read pages: write id-token: write concurrency: group: pages cancel-in-progress: false jobs: deploy: environment: name: github-pages url: ${{ steps.deployment.outputs.page_url }} runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - name: Setup Pages uses: actions/configure-pages@v5 - name: Upload artifact uses: actions/upload-pages-artifact@v3 with: path: '.' - name: Deploy to GitHub Pages id: deployment uses: actions/deploy-pages@v4逐段解释一下:
on.push.branches:只在main分支收到推送时触发。workflow_dispatch:允许你在 Actions 页面手动点击Run workflow,用于重新发布。permissions:声明工作流需要的权限。pages: write用于发布,id-token: write用于 GitHub Pages 部署时的身份验证。concurrency:防止多个部署任务同时运行,避免发布状态冲突。actions/upload-pages-artifact:把根目录内容打包为部署产物。actions/deploy-pages:真正把产物发布到 Pages。
保存 Workflow 后,回到仓库的 Actions 标签页,能看到这个工作流正在运行。等它跑完,去仓库 Settings -> Pages 页面,会发现发布来源已经变成GitHub Actions。
如果使用 Jekyll,工作流需要在Upload artifact之前增加构建步骤,核心命令是:
bundle exec jekyll build --baseurl "${{ steps.pages.outputs.base_path }}"这里--baseurl很关键,项目部署在子路径时,缺少它会找不到样式和链接。
4.3 触发构建后从哪里看结果
每次推送代码,进入 Actions 页面,点开最新一次运行记录,可以看到每个 Step 的状态。绿色对勾表示成功,红色表示失败。
失败时需要重点看两个地方:
- 失败的 Step 日志中是否有报错关键字,比如
error、Command failed、Cannot find module。 - 日志中打印的文件路径是否和仓库实际目录一致。
GitHub Actions 的日志是排错的第一入口,不要只看最终结果。日志里会显示执行环境、依赖安装结果、构建命令输出,这些信息比“部署失败”四个字有用得多。
5. 进阶:用 Jekyll 管理内容和主题
5.1 Jekyll 的核心工作方式
Jekyll 是一个静态站点生成器,它把 Markdown 和模板文件组合成静态 HTML。你不需要每次手动改 HTML 里的重复导航、页脚、文章列表,写完 Markdown 后运行构建命令,Jekyll 会自动生成完整页面。
理解 Jekyll 只需要抓住三个概念:
_config.yml:站点全局配置。- Front Matter:Markdown 文件头部用
---包裹的元数据。 - Layout:页面模板,多个内容页共用同一个布局。
这种工作方式非常适合个人主页和博客,因为内容维护成本很低。你只需要专注写 Markdown,页面结构和样式交给模板管理。
5.2 目录结构和 Front Matter
一个典型的 Jekyll 个人主页结构如下:
. ├── .github/ │ └── workflows/ │ └── deploy.yml ├── _config.yml ├── _posts/ │ └── 2026-01-01-welcome.md ├── assets/ │ └── style.css ├── about.md ├── index.md └── 404.md_config.yml是最重要的配置文件:
title: 我的个人主页 description: 这里有我的项目记录和技术思考 baseurl: "" url: "https://username.github.io" theme: minima如果仓库名是username.github.io,baseurl一般保持空字符串。如果部署在/repo/路径下,baseurl要写成"/repo",这个值必须和访问路径保持一致。
Markdown 文件头部可以写 Front Matter。以index.md为例:
--- layout: home title: 首页 --- # 你好,我是 [你的名字] 这里可以写一段简短的介绍。layout的值取决于你使用的主题。minima主题提供home、page、post等布局,具体名称以主题文档为准。
文章文件必须放在_posts目录,命名格式是YYYY-MM-DD-标题.md:
--- layout: post title: "2026 年的第一个更新" date: 2026-01-01 --- 这是文章的正文内容。Jekyll 会根据文件名中的日期自动归类,所以不要随意改这个命名规则。
5.3 本地预览 Jekyll 站点
先在本地安装 Ruby 环境,然后安装 Jekyll 和 Bundler:
gem install jekyll bundler如果你是从零创建 Jekyll 项目:
jekyll new my-site cd my-site bundle install启动本地开发服务器:
bundle exec jekyll serve打开http://127.0.0.1:4000,就能实时预览页面。修改 Markdown 或配置文件后,刷新浏览器即可看到效果。确认无误后,提交源码并推送,Actions 会负责在云端完成构建和部署。
本地预览最大的价值是减少线上试错。你可以在本地先发现链接失效、样式错乱、文章列表异常,而不是推送到 GitHub 后再看构建日志。
6. 自定义域名和 HTTPS 证书
6.1 域名解析记录怎么设置
默认的username.github.io地址已经可以访问,但它不够个性化。绑定自己的域名后,主页入口更专业,也方便记忆。
到你的域名服务商后台,添加两条解析记录。GitHub Pages 官方文档提供的常见配置如下:
| 主机记录 | 记录类型 | 记录值 |
|---|---|---|
@ | A | 185.199.108.153 |
@ | A | 185.199.109.153 |
@ | A | 185.199.110.153 |
@ | A | 185.199.111.153 |
www | CNAME | username.github.io. |
A 记录用于根域名,比如example.com。CNAME 记录用于www.example.com,让它指向你的 GitHub Pages 默认域名。
不同域名服务商对“根域名”的表达不同,有的叫@,有的叫“空名称”。配置后需要等待 DNS 生效,TTL 越短,生效越快。
6.2 在仓库中绑定自定义域名
打开仓库 Settings -> Pages,在Custom domain一栏输入你的域名,比如example.com,点击 Save。
保存后,GitHub 会在你的仓库里自动创建或更新一个CNAME文件,文件内容就是你的自定义域名。你不需要手动维护这个文件,但要注意不要手动删除它。
在 Pages 设置页面绑定后,会在同一个位置看到Enforce HTTPS选项。建议立刻勾选开启,这样访问者会强制使用 HTTPS 连接,证书由 GitHub 自动签发。
如果需要使用www.example.com作为主访问地址,就在 CNAME 文件里填写www.example.com;如果使用根域名,就填写example.com。GitHub 通常会做跳转,但主域名只能选一个。
6.3 HTTPS 自动签发后的验证
正确配置 DNS 后,在终端执行:
curl -I https://username.github.io会返回类似HTTP/2 200的结果。绑定自定义域名后,再执行:
curl -I https://example.com如果返回301跳转,说明域名还没有完全生效或需要等待证书签发。HTTPS 证书不是立刻生成的,DNS 记录生效后,通常还要等待几分钟到几个小时。
在浏览器里访问你的域名,点击地址栏左侧的小锁图标,查看证书是否有效。如果证书提示不安全,优先检查 DNS 记录是否填错,以及 CNAME 文件里是否有多余空格或重复域名。
7. 发布后的验证、常见问题和排查路径
7.1 页面发布成功不等于内容正确
很多人在看到页面能打开后,就认为部署完成了。但“能打开”和“内容正确”是两回事。
完整验证应该覆盖这几个维度:
- 首页是否显示最新内容。
- 图片和 CSS 是否能正常加载,浏览器控制台有没有 404 或 MIME type 报错。
- 自定义域名是否生效,HTTP 是否跳转到 HTTPS。
- 手机端布局是否正常,导航、按钮、链接是否可点击。
- 404 页面是否能正常显示,并且能返回首页。
- 仓库 Actions 的最新一次运行是否为成功状态。
建议在无痕窗口里访问,避免浏览器缓存干扰判断。完成一次发布后,用无痕窗口强制刷新,看到的才是真实线上效果。
7.2 Actions 日志和仓库设置是排查入口
遇到部署问题时,不要凭感觉改代码。先确定问题发生在哪一层。
第一层是仓库本身。检查index.html是否在指定目录,文件名是否准确,分支名是否和 Pages 设置一致。
第二层是构建流程。进入 Actions 标签页,查看最新一次运行日志。如果构建 Step 失败,日志中通常有明确的错误信息。
第三层是域名和证书。如果页面能通过username.github.io访问,但自定义域名打不开,问题大概率在 DNS 解析或 CNAME 文件,而不是代码。
第四层是浏览器缓存。如果代码和 Actions 都正常,但看到的是旧页面,先刷新,再用无痕窗口验证。
7.3 常见问题速查表
| 问题现象 | 可能原因 | 检查方式 | 处理建议 |
|---|---|---|---|
| 页面一直显示旧内容 | 浏览器或 CDN 缓存 | 无痕窗口访问,查看 Actions 运行时间 | 等待几分钟后强制刷新,确认最新提交已触发部署 |
| 访问返回 404 | 仓库名不对或没有index.html | 检查username.github.io仓库名,检查发布目录 | 重命名仓库,或在发布目录放一个index.html |
| 自定义域名不生效 | DNS 记录类型或地址错误 | 使用dig或Resolve-DnsName查询解析记录 | 对照 GitHub Pages 官方文档修改 A/CNAME 记录,等待 TTL 生效 |
| HTTPS 证书一直未签发 | DNS 未完成或 CNAME 文件有问题 | 在 Pages 设置查看证书状态,检查 CNAME 文件 | 等待 DNS 生效,确保 CNAME 文件只有一行域名 |
| Actions 构建失败 | YAML 语法错误或依赖版本不一致 | 进入 Actions 日志查看失败 Step | 修正 Workflow 文件,确认 Ruby、Bundler、Node 版本配置 |
| 样式加载不出来 | CSS 路径错误或 baseurl 错误 | 打开浏览器控制台看资源加载结果 | 调整<link>路径或在 Jekyll 中使用relative_url |
| 使用 Jekyll 但页面没有任何样式 | baseurl和实际部署路径不一致 | 检查_config.yml和页面源码里的链接 | 项目部署在子路径时,给样式和链接加上 baseurl |
这套排查顺序的核心是:先确认输入,再看路径,再查依赖版本,最后看网络和缓存。如果一开始就怀疑域名或 CDN,反而容易绕路。
8. 个人主页的内容组织和长期维护建议
8.1 页面结构怎么设计
个人主页不需要把所有内容都堆在首页。对于开发者来说,首页最值得保留的是“你是谁、你在做什么、怎么联系你”这三件事。
推荐的导航结构:
- 首页:一句话介绍和核心项目入口。
- 关于:详细经历、技术栈、教育或工作背景。
- 项目:列出 2 到 4 个有代表性的项目,每个项目说明解决的问题、技术方案和仓库链接。
- 博客或笔记:记录踩坑经历、学习笔记、项目复盘。
首页不要写太长。真正能打动人的个人主页,通常是打开后 3 秒内就能看懂你是做什么的。详细内容放在二级页面,让读者自己选择点进去看。
8.2 发布前检查清单
每次更新完主页,建议按下面清单检查一遍:
- 确认改动已经提交并推送到正确分支。
- 确认
index.html或 Jekyll 首页内容已更新。 - 确认新增文图片使用相对路径,避免子路径下失效。
- 确认自定义域名解析和 HTTPS 证书状态正常。
- 确认没有把密钥、
.env文件、数据库连接串提交到仓库。 - 确认 Actions 日志全部通过。
- 确认无痕窗口访问后页面样式、链接、404 页面正常。
这个清单可以在每次发布时固定使用。它不需要很复杂,但能避免最常见的“推上去就忘,等真出问题才发现”。
8.3 学习环境、测试环境、生产环境的差异
在本地运行bundle exec jekyll serve时,很多问题不会暴露,因为路径、环境变量和线上不一样。学习环境的目标是快速看到页面效果,所以可以忽略性能、缓存、域名问题。
测试环境一般就是你的username.github.io默认域名。这里可以验证部署流程、文章内容和样式是否符合预期,但还没有正式绑定自定义域名。
生产环境则是你绑定自定义域名、开启 HTTPS 后的正式站点。进入生产环境后,还需要额外考虑:
- 页面访问速度和资源体积。
- 图片是否经过压缩。
- 是否配置了站点地图和 SEO 基础信息。
- 是否开启了访问统计。
- 是否有回滚方案,比如保留上一个提交的 tag。
对于个人主页,不需要一开始就做到企业级复杂度。但至少要保持“每次提交都能构建、每次构建都可回滚”的底线,这样长期更新时心里才有底。
8.4 后续扩展方向
GitHub Pages 虽然是静态托管,但它可以承载的内容其实不少。后续可以逐步加入:
- Jekyll 博客和文章分类。
- RSS 订阅地址。
- 通过第三方评论服务实现文章评论区。
- 使用 GitHub API 展示仓库和 stars 数量。
- 增加暗色模式切换。
- 为项目页面单独写 README 和部署说明。
到这一步,你已经不只是完成了一个个人网站主页,而是掌握了一条完整的“源码管理 + 自动构建 + 静态托管 + 自定义域名”的发布链路。这条链路不只能用于个人主页,也能迁移到项目文档站、团队介绍页、产品落地页等场景。
个人主页最值得投入的不是一次性把页面做得多炫,而是持续更新。每完成一个项目,就在主页上补充一条记录;每踩过一个坑,就写一篇笔记。保持这个习惯比任何花哨的动画都比不上。