从零配置个人博客网站

Jackknifer
Jackknifer 博主

这篇文章记录我搭建个人博客的过程。网站使用 Hexo、Theme Redefine 和 GitHub Pages,绑定 jackknifer.me,并通过 GitHub Actions 发布。文章涵盖站点配置、日常写作、自定义域名和常见问题。

1. 准备账号和本地环境

1.1 准备 GitHub 仓库

注册 GitHub 账号,并记下账号名。个人站点的仓库名使用 <用户名>.github.io。本项目的仓库名是 Jackknifer.github.io,默认分支是 main。GitHub Pages 官方入门文档介绍了仓库命名规则。

在 GitHub 新建仓库时,填写准确的仓库名。准备从本地上传完整 Hexo 项目时,仓库可以保持空白。

使用 GitHub Free 的个人账号时,公开仓库可以使用 GitHub Pages。使用私有仓库发布 Pages,需要符合 GitHub 当前方案要求。私有仓库发布的网站仍可公开访问。

1.2 安装 Node.js 和 Git

本项目使用 Node.js 24。安装 Node.js 24 和 Git 后,打开终端检查版本:

1
2
3
node --version
npm --version
git --version

本项目根目录的 .nvmrc 写有 24。现有仓库使用 npm ci 按 package-lock.json 安装依赖。新建项目需要先生成锁文件,后续安装才使用 npm ci。

2. 创建 Hexo 项目

2.1 初始化站点

Hexo(静态网站生成工具)将 Markdown 文章生成网页。按照 Hexo 安装文档和初始化文档执行:

1
2
3
4
npm install -g hexo-cli
hexo init my-blog
cd my-blog
npm install

若希望复现本项目的主要版本,安装 Hexo 8.1.2 和 Theme Redefine 2.9.0:

1
npm install --save-exact hexo@8.1.2 hexo-theme-redefine@2.9.0

打开编辑器,在项目根目录新建 .nvmrc,写入 24。保留 package-lock.json,并提交到仓库。node_modules/ 和 public/ 应加入 .gitignore。

2.2 配置站点地址与文章路径

编辑根目录的 _config.yml。以下内容展示本项目采用的关键设置;保留 Hexo 生成的其他设置:

1
2
3
4
5
6
7
8
9
10
11
title: 个人博客
description: 记录文章与近况。
author: 你的名字
language: zh-CN
timezone: Asia/Shanghai
url: https://USERNAME.github.io
permalink: :year/:month/:day/:title/
date_format: YYYY-MM-DD
time_format: ''
updated_option: 'empty'
theme: redefine

将 USERNAME 改成自己的 GitHub 用户名。绑定自定义域名后,同时修改 url。永久链接含日期;发布旧文章时,date 将影响网页地址。已经公开的文章应谨慎修改 date 和文件名。

updated_option: 'empty' 避免自动使用文件修改时间。本项目的页面仅显示年月日。Theme Redefine 的首页日期格式还需设置为 home.article_date_format: YYYY-MM-DD。

2.3 配置 Theme Redefine

Theme Redefine(博客主题)的安装说明要求在 Hexo 根目录新建 _config.redefine.yml。用编辑器打开 node_modules/hexo-theme-redefine/_config.yml,将主题配置复制到新文件。以后在根目录的 _config.redefine.yml 编辑主题设置。

本项目主要修改以下配置项:

  • info.title、info.author 和 info.url:站点名称、作者与网页地址。
  • defaults.avatar:头像地址,例如 /images/avatar.jpg。
  • home_banner.image.light 和 home_banner.image.dark:首页背景图片。
  • navbar.links:首页、文章索引和普通页面入口。
  • home.sidebar:个人介绍与侧边栏导航。
  • home.article_date_format:首页文章日期格式。
  • global.open_graph:网页分享预览的基础设置。
  • comment:评论功能及对应仓库。
  • inject.head 和 inject.footer:自定义资源引用。

主题升级时,比较根目录配置和新版本主题配置,再处理新增或改名的项目。主题安装目录位于 node_modules/,安装依赖时会重新生成。

2.4 建立页面与导航

Hexo 的文章位于 source/_posts/。普通页面可以使用 npx hexo new page about 创建,然后编辑 source/about/index.md。标签页和分类页也可以分别创建,并填写 type: tags、type: categories。

本项目还有 source/now/index.md、source/moments/index.md。其中,moments 页面依赖 scripts/moments.js 和相关脚本;刚创建的 Hexo 项目需要同时加入这些文件,才能使用本项目的动态功能。

创建页面后,在 _config.redefine.yml 的 navbar.links 加入相应路径。检查导航地址和生成页面的地址一致。

2.5 本地生成与预览

新建的标准 Hexo 项目可以执行:

1
2
3
npx hexo clean
npx hexo generate
npx hexo server

浏览器打开 http://localhost:4000/。检查首页、文章页、标签页和分类页。终端运行中的预览服务可用 Ctrl+C 结束。Hexo 命令文档列出了文章与站点命令。

现有 Jackknifer 项目使用 npm run server、npm run build 和 npm run clean。这些命令还会生成浏览器脚本与图片变体,并通过 tools/hexo.mjs 统一设置构建时区。已经克隆本项目时,应使用这些 npm 命令。

3. 编写文章与管理图片

3.1 创建文章

在标准 Hexo 项目运行 npx hexo new post "文章标题"。在本项目运行 npm run new:post -- "文章标题",或在 VS Code 的 source/_posts/ 中新建 Markdown 文件。

文章开头填写 Front Matter(文章元信息):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
---
title: 文章标题
date: 2026-09-23 21:39:00
tags:
- 标签名
categories:
- 分类名
description: 用一句话介绍这篇文章。
cover: /images/posts/文章标题/封面.jpg
---

这里编写文章正文。

![照片说明](/images/posts/文章标题/照片一.jpg)

用真实的写作或发布日期填写 date。补发旧文时,可以填写原来的日期。description 用于文章摘要和分享说明;cover 留空时,本站的分享图片使用首页背景图。

正文每段之间保留空行。Hexo 写作说明介绍了 Front Matter 与 Markdown。

3.2 放置图片

本项目将文章图片放在 source/images/posts/<文章标题>/。例如,source/images/posts/文章标题/照片一.jpg 对应文章中的 /images/posts/文章标题/照片一.jpg。

图片移动或改名后,同步修改 cover 和正文链接。逐一检查文件名、扩展名和大小写。公开页面中出现图片空白时,先确认对应文件已经提交,并检查生成目录 public/images/ 中的真实路径。

本项目的 npm run build:images 会为有收益的图片生成尺寸变体。文章继续引用 source/images/ 中的原图。构建生成的 source/images/optimized/ 和 source/_data/image-variants.json 已被忽略。

3.3 管理草稿和旧文章

本项目的 source/_drafts/ 保存草稿。使用 npm run server:drafts 本地预览,使用 npm run publish -- "草稿文件名" 发布。

大量旧文章可以先放入 pending-posts/。这个目录中的实际文章受到 .gitignore 规则保护。每篇文章可以使用一个独立文件夹,保存 index.md、cover.jpg 和正文图片。文章中用相对路径引用收件箱内的图片,例如 ![照片说明](./images/photo-1.jpg)。

在本项目中检查并导入:

1
2
npm run import:pending:dry
npm run import:pending

导入工具把正式文章复制到 source/_posts/,把图片复制到 source/images/posts/。导入输出如提示缺少图片,补齐图片后重新检查文章。导入命令可能已经处理其他文章,需要查看输出与正式目录。

覆盖已有文章的命令是 npm run import:pending:force。执行前应核对正式版本和收件箱内容。

文章、草稿和导入的完整图形界面操作,记录在项目中的 BLOG_GUIDE.md、source/_posts/_README.md 和 source/_moments/_README.md。

4. 使用 GitHub Actions 发布

4.1 上传站点源码

在 GitHub 创建名为 <用户名>.github.io 的空仓库。本地项目完成预览后,先运行 git status。若提示当前目录尚未建立 Git 仓库,再运行 git init -b main。

确认本地仓库已经存在后,运行下列命令。请将远端地址改成自己的仓库地址:

1
2
3
4
git remote add origin https://github.com/USERNAME/USERNAME.github.io.git
git add _config.yml _config.redefine.yml .gitignore .nvmrc package.json package-lock.json scaffolds source
git commit -m "Create Hexo blog"
git push -u origin main

远端地址已经存在时,使用 git remote set-url origin <仓库地址> 修改。每次提交前,使用 git status 查看变更范围。

4.2 设置 Pages 发布源

GitHub Pages(静态网站托管服务)需要读取生成的 public/。进入仓库的 Settings → Pages,在 Build and deployment → Source 选择 GitHub Actions。GitHub 发布源说明列出了完整操作。

在 .github/workflows/pages.yml 创建工作流。以下配置适用于标准 Hexo 项目,构建时运行仓库安装的 Hexo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
name: Pages

on:
push:
branches:
- main
pull_request:
branches:
- main
workflow_dispatch:

permissions: {}

jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
pages: read
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020
with:
node-version: 24
cache: npm
- if: github.event_name != 'pull_request'
uses: actions/configure-pages@45bfe0192ca1faeb007ade9deae92b16b8254a0d
- run: npm ci
- run: npx hexo clean
- run: npx hexo generate
- run: npm audit --audit-level=moderate
- if: github.event_name != 'pull_request'
uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9
with:
path: ./public

deploy:
if: github.event_name != 'pull_request'
needs: build
runs-on: ubuntu-latest
permissions:
pages: write
id-token: write
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- id: deployment
uses: actions/deploy-pages@cd2ce8fcbc39b97be8ca5fce6e763baed58fa128

本项目的发布工作流位于 .github/workflows/pages.yml。工作流还运行 npm run check,并在部署后发送 IndexNow 通知。该文件依赖本仓库的 tools/、scripts/ 和 client/。采用本项目源码时,直接使用已有工作流。

工作流文件提交并推送后,在仓库的 Actions 页面打开当前提交对应的运行记录。确认 build 和 deploy 都成功,再访问 https://USERNAME.github.io/。推送完成仅说明代码到达仓库;网页发布以部署记录和公开页面检查为准。

4.3 日常更新

在 VS Code 编辑文章、图片和配置。运行本项目的构建与检查命令:

1
2
3
npm ci
npm run build
npm run check:assets

npm ci 用于新克隆的目录,以及需要重新安装锁定依赖的情况。当前仓库还提供 npm run verify,它会清理、构建并运行完整检查。使用 Git 提交时,只添加本次确认要发布的文件:

1
2
3
4
git status
git add source/_posts/文章标题.md source/images/posts/文章标题
git commit -m "发布文章:文章标题"
git push origin main

提交后检查 Actions,再打开公开文章地址。使用 VS Code 左侧“源代码管理”中的“提交”和“同步更改”,也可以完成 Git 提交与推送。修改网站功能时,提交前还应检查文章正文的 Git 差异,确认原文保持完整。

5. 绑定自定义域名

5.1 注册并核对域名

本项目使用 jackknifer.me。注册时使用了 GitHub Student Developer Pack 中的 Namecheap .me 优惠。拥有学生权益的读者,可以在 GitHub Education 优惠页面查找 Namecheap 并进入领取页面。

该优惠提供一年的注册权益。领取前查看当前条件、续费价格、自动续费设置和域名控制权。普通域名也可以从支持 DNS 管理的注册商购买。

选定唯一的公开地址。例如,本项目使用 https://jackknifer.me。网站标题与 GitHub 仓库名可以继续保留,网页地址统一使用新域名。

5.2 验证域名所有权

进入个人 GitHub 账号的 Settings → Pages → Add a domain。按照 GitHub 显示的内容,在域名注册商处新增 TXT 记录,完成验证,并保留这条记录。GitHub 域名验证说明给出了界面位置和检查命令。

TXT 记录的名称和值以自己账号的 GitHub 页面为准。完成域名验证后,进入博客仓库的 Settings → Pages → Custom domain,填写主域名并保存。

5.3 设置 DNS

以根域名 example.com 为例,在域名注册商处设置 @ 的 A 记录。GitHub 当前文档列出的地址是:

1
2
3
4
185.199.108.153
185.199.109.153
185.199.110.153
185.199.111.153

如果同时使用 www.example.com,将 www 的 CNAME 指向 USERNAME.github.io。GitHub 会按 Pages 中保存的主域名处理两者的跳转。检查并清理冲突的旧 DNS 记录。保留域名验证使用的 TXT 记录。具体记录和值请以 GitHub 自定义域名文档为准。

本项目保留了根目录 CNAME 和 source/CNAME。使用 GitHub Actions 发布时,仓库的 Pages 设置负责保存自定义域名;工作流无需依赖 CNAME 文件。

5.4 修改站点配置并检查 HTTPS

修改 _config.yml 的 url、_config.redefine.yml 的 info.url、source/robots.txt 中的站点地图地址,以及文档中的公开网站链接。重新构建后,检查每篇文章的 canonical URL、分享 URL 和 sitemap.xml。仓库名称、GitHub Discussions 地址仍使用各自的真实地址。

在仓库 Settings → Pages 检查域名状态,并启用 Enforce HTTPS。证书需要 GitHub 完成 DNS 检查后签发。若 www 地址出现证书警告,检查 www 的 CNAME、根域名的 A 记录、冲突记录,以及 Pages 中保存的域名。GitHub HTTPS 文档列出了证书与混合内容检查方法。

验证公开地址和跳转:

1
2
3
curl -I https://example.com/
curl -I https://www.example.com/
curl -I https://USERNAME.github.io/

主域名应返回 200。辅助地址应跳转到选定的主域名。对文章地址也执行检查,确认旧网址跳转后保留文章路径。

6. 让搜索引擎发现文章

6.1 生成站点地图与页面信息

给文章填写准确的 title 和 description。安装 Hexo 的站点地图生成器:

1
npm install --save-exact hexo-generator-sitemap@3.0.1

构建后检查 public/sitemap.xml。站点地图应列出希望被搜索的规范地址,并排除 404.html。source/robots.txt 中填写站点地图的完整地址。本项目使用 templates/sitemap.xml 设置生成内容。scripts/post-share-meta.js 生成文章 canonical、Open Graph(分享预览信息),tools/check-content.mjs 检查站点地图与规范地址。

Google 的站点地图文档说明,提交站点地图是发现网址的提示。提交记录与搜索结果的收录时间需要分别查看。

6.2 提交搜索工具

在 Google Search Console 验证域名,提交 https://example.com/sitemap.xml。在 Bing Webmaster Tools 添加同一站点并提交站点地图。本项目的 GitHub Actions 还会在部署完成后运行 notify-indexnow,向支持 IndexNow 的服务通知新网址。

更换域名时,保留旧地址跳转,并在新域名对应的搜索工具中提交站点地图。验证新旧域名后,在旧域名的 Search Console 资料中提交 Change of Address(地址变更)。Google 网站迁移说明列出了相关步骤。

Search Console 的“网页会自动重定向”状态,表示被检查的源地址发生跳转。继续检查最终文章地址是否返回 200、页面是否允许索引,以及目标是否对应原文章。

7. 维护评论与自定义功能

本项目在 _config.redefine.yml 配置了 Giscus(基于 GitHub Discussions 的评论服务)。Giscus 配置页面要求评论仓库公开、启用 Discussions,并安装 Giscus 应用。选择私有源码仓库时,评论功能需要使用符合这些条件的仓库,并重新核对 repo、repo_id、category 和 category_id。

本项目的音乐、天气、动态页面和资源加载处理还依赖 client/、scripts/、tools/、source/css/ 与 source/media/。这些功能由本仓库维护,标准 Hexo 初始化结果中没有相应文件。天气使用网络地址获取城市,再读取天气数据;网络服务不可用时,应检查页面的提示和重试入口。

8. 常见情况的检查方法

8.1 本地命令无法运行

出现 hexo: command not found 时,在项目根目录执行 npm ci,再使用本项目的 npm 命令。检查 Node.js 版本是否符合 .nvmrc。标准 Hexo 项目可以使用 npx hexo 调用本地依赖。

构建提示 Theme Redefine 版本查询失败时,查看构建命令的退出状态和 public/ 生成结果。项目历史中出现过主题版本服务的 DNS 提示;构建与内容检查当时仍成功。

8.2 日期或文章地址异常

本项目的 tools/hexo.mjs 设置 TZ=UTC,_config.yml 使用 Asia/Shanghai 展示日期。文章 Front Matter 建议填写完整的北京时间。发布前同时检查页面日期和 public/YYYY/MM/DD/ 目录。项目曾遇到页面日期正确、网址日期提前一天的情况;完整时间和构建检查可以发现该问题。

8.3 图片或页面组件缺失

检查原图是否位于 source/images/,文章地址是否以 /images/ 开头,以及文件名大小写是否一致。完成构建后,再检查 public/images/ 中的对应文件。媒体文件应采用浏览器可播放的格式;本项目使用 MP3 文件。

移动端出现导航、头像、播放器或天气组件缺失时,先检查站点资源请求和第三方服务请求。当前项目把基础页面内容直接写入生成网页,资源失败时保留图片重试和组件提示。

主题配置中的 global.single_page、global.preloader.enable 和 global.website_counter.enable 当前均为 false。这些设置减少了对外部脚本及页面加载动画的依赖。修改相关功能后,需要检查真实桌面与移动设备上的加载结果。

8.4 部署与域名状态异常

查看当前提交对应的 Actions 运行记录。build 成功后还需检查 deploy。若域名仍显示旧网页,检查 Pages 中保存的域名、最新部署时间、DNS 记录和浏览器缓存。

HTTPS 证书警告可按第 5 节检查 DNS 与 Pages 状态。若公开文章的常用地址跳转到首页,检查站点 url、文章永久链接和目标网页。域名切换后,旧域名的正常跳转可以继续保留。

8.5 搜索工具尚未显示文章

直接打开文章地址,确认 HTTP 状态为 200。检查页面的 canonical、robots 设置和站点地图中的网址。使用 Google Search Console 的网址检查工具查看具体页面,再观察收录状态。提交站点地图不会保证立即收录,也不会保证搜索排名。

9. 本项目的维护入口

  • 站点设置:_config.yml。
  • 主题设置:_config.redefine.yml。
  • 文章与图片:source/_posts/、source/images/posts/。
  • 草稿与旧文收件箱:source/_drafts/、pending-posts/。
  • 动态内容:source/_moments/ 和 scripts/moments.js。
  • 自定义样式与交互:source/css/ 和 client/。
  • 生成与检查命令:package.json 和 tools/。
  • 自动发布:.github/workflows/pages.yml。
评论

评论由 GitHub Giscus 提供。若当前网络无法加载,可 前往 GitHub Discussions 查看或参与讨论。