使用Hexo搭建可自动同步的个人博客

近日我把个人博客从 WordPress 迁到了 Hexo,迁移的原因有两点:

  • WordPress 是动态框架,每次运行都要动态生成内容(即使有缓存插件还是需要运行 PHP 脚本),不仅让网站访问的速度降低了,而且我觉得这种可以通过用户名和密码认证来直接在 Web 页面上获取网站管理权限的机制,不如直接部署 HTML 静态页面安全(毕竟静态页面不用运行 PHP 代码);
  • WordPress 在写文章的时候只能开着浏览器在线上写,文章数据也只能保存在服务器中,对于之前由于服务器无法登录而损失了宝贵数据的我来说,文章数据还是放在本地更加放心。另外,将文章从 WordPress 导出来比较困难,平时写的一些文章我也会将它们发布到简书、公众号上等,没有文章的 Markdown 文件是比较麻烦的一件事。

综上所述,既能使用静态文件生成网站,又能为我在本地保留 Markdown 文件的个人博客框架,那就首选 Hexo 了,至于为什么不选其他的静态框架,是因为我同学的博客也是用 Hexo 搭建的,所以我对这个比较熟悉。

下面就开始讲如何使用 Hexo 搭建个人博客。(Hexo 官方网站:https://hexo.io/zh-cn/

一、架构概述

我在网上看到很多使用 Hexo 搭建个人博客的教程,使用的是 Github Pages 功能,将 Hexo 生成的 HTML 上传到 GitHub 的 Repo 里,开启 Pages 功能就可以通过 Github.com 的二级域名进行访问了。这种部署方式很方便,也不需要自己有服务器和域名,适合不想折腾太多的人。

这篇文章介绍的是使用自己的服务器来进行部署,以及使用 Github 的 Webhooks 自动更新服务器上的静态资源,Github 只是一个文件的中转站和备份,这么做的原因是我还有其他的服务挂在域名上,而那些服务需要 PHP 运行环境。

大概的架构图为:

网站架构图

在文章更新的时候,大概流程是:

  • 本地计算机执行 git push
  • Github 触发 push 事件,启动 Webhook,将事件信息通过 HTTP POST 发送给服务器上的特定路径的 PHP 脚本
  • 脚本运行 git pull 命令,更新 Hexo 资源目录

二、安装 Hexo

使用 Hexo 搭建个人博客的第一步当然是安装 Hexo 了,在本地安装 Hexo 需要先安装 Node.js 运行环境,Hexo 使用 npm 包管理器进行安装。

1.安装 Node.js

Node.js 官网地址为:https://nodejs.org/zh-cn/,进入官网后建议选择【长期支持版】进行下载,下载后跟随安装界面一路下去即可。如果下载速度太慢,可以使用淘宝 npm 镜像下载,地址为:https://npm.taobao.org/mirrors/node

安装过程完成后,可以在命令行执行

1
node --version

查看是否可以显示 Node.js 的版本号,如果显示就说明安装成功了。

2.安装 Hexo

安装 Node.js 后,就是安装 Hexo 框架了。打开命令行(Cmd 或 PowerShell)执行命令:

1
2
# 安装Hexo-cli,Hexo本体
npm install hexo-cli -g

等待其运行成功后,执行

1
hexo -v

出现如下输出即为安装成功

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
hexo-cli: 3.1.0
os: Windows_NT 10.0.18363 win32 x64
node: 12.13.0
v8: 7.7.299.13-node.12
uv: 1.32.0
zlib: 1.2.11
brotli: 1.0.7
ares: 1.15.0
modules: 72
nghttp2: 1.39.2
napi: 5
llhttp: 1.1.4
http_parser: 2.8.0
openssl: 1.1.1d
cldr: 35.1
icu: 64.2
tz: 2019a
unicode: 12.1

3.安装 Git

现在来安装 Git,用于网站生成完成后的部署。

首先下载 Git 安装程序:https://git-scm.com/downloads,选择符合自己的平台下载即可,如果下载速度太慢可以使用淘宝镜像:https://npm.taobao.org/mirrors/git-for-windows/(或者复制链接使用迅雷下载,我试了一下还挺快)。

下载完成后运行程序,如果有 Add Git to Path 的选项请勾选。然后打开命令行(CMD 或者 PowerShell)输入:

1
git --version

显示版本即安装成功。

三、创建 Git Repository

我们使用 Github 来作为网站的备份和版本控制,这里我们将创建两个 Repository,一个用来放置网站的源代码,对于 Hexo 来说就是 Markdown 文件和各种配置文件。另一个用来放置 Hexo 生成的网页内容,并设置 Webhook 和我们的服务器保持同步。

💡

针对没有使用过 Github 的同学,需要先设置 SSH Key,点击 Github 右上角的头像,点击 Settings 进入设置,选择左侧的 SSH and GPG Keys,然后点击右边的绿色的 New SSH Key 按钮。然后打开 PowerShell,输入命令

ssh-keygen -t rsa

然后一路回车即可,就会在系统盘你的用户目录下的 .ssh 目录多出来一个 id_rsa 文件,这是你的私钥,另外会有一份 id_rsa.pub 文件,这是你的公钥,使用笔记本打开 pub 文件,复制里面的所有内容。然后在 Github 刚才打开的页面中把复制的内容添加到 Key 一栏中,并写一个Title 点击 Add SSH Key 按钮即可。

首先创建第一个用于托管源文件的 Repository。

登录 Github,创建一个新的 Repository,设置权限为 Private(仅自己可见),这里命名为“Hexo-Source”,并初始化一个 Readme.md 文件。如下图:

相似的,我们再创建一个新的 Repository 用来托管网站生成后的文件,这里命名为“Hexo-Website”,同样也设置为 Private。

现在我们就有了两个 Github Repository,接下来就是生成网站的步骤了。

四、创建 Hexo 项目

首先要把 Github 上的 Hexo-Source Repository 克隆下来。

然后我们打开 PowerShell,使用 CD 命令进入想要存储刚才克隆的 Repository 目录,执行下面的代码进行项目的初始化:

1
2
3
hexo init <folder>
cd <folder>
npm install

其中的 <folder> 替换为你的项目名称。

初始化完成以后的目录结构是这样的:

1
2
3
4
5
6
7
8
.
├── _config.yml
├── package.json
├── scaffolds
├── source
| ├── _drafts
| └── _posts
└── themes
  • _config.yml - 项目的配置文件(主要需要修改的配置文件)
  • package.json - 应用程序的信息(一般不用修改)
  • scaffolds - 新建文章时程序使用的模板
  • source - 存储文章 Markdown 源码的目录
    • _drafts - 文章草稿源码
    • _posts - 发布的文章源码
  • themes - 主题目录(将自己想用的主题文件放在此文件夹中)

关于各种目录具体的用途,请参考官网文档:https://hexo.io/zh-cn/docs/setup

五、配置网站

创建项目后,这只是一个默认的模板,我们需要在网站中添加自己的信息,修改网站的主题等,使得它更像“自己的个人博客”。

首先需要修改的是 _config.yml 文件,关于这个文件的具体配置项,请参考文档:https://hexo.io/zh-cn/docs/configuration,下面简要介绍一下常用的配置。

配置项名称 用途 常用值
title 网站名称,即显示在浏览器标题栏中的名称。 你的网站名称
subtitle 网站副标题,会被一些主题使用,显示在主页上。 你的副标题
description 网站描述,用于搜索引擎或者爬虫等。 你的网站描述
keywords 概括网站内容的关键词,用于搜索引擎或者爬虫等,使用逗号分隔。 你的关键词。
author 作者名称,也就是你的名称(昵称)。 你的名称。
language 网站语言,网站生成后的一些通用功能显示的语言。 zh-Hans
timezone 网站的时区。 ‘Asia/Shanghai’
url 你的网站所部署的路径地址,例如我的网站就是 https://maphical.cn,支持子目录,例如 https://maphical.cn/blog 你所计划的网站访问地址
root 你的网站根目录的路径。 /
permalink 博客文章的永久链接格式,可查阅文档了解构造方式。 :year/:month/:title/
date_format 日期显示格式。 YYYY-MM-DD
time_format 时间显示格式。 HH:mm:ss
theme 主题名称,填写 theme 目录下的主题目录的名称,可以自己下载主题放入此目录中。 你的主题目录名称
plugins(非必要修改) 网站所使用的插件。 插件名称
feed(非必要修改) 这项是使用了 hexo-generator-feed 插件后才需要指定的,用于生成网站的 RSS 源。 有三项配置:type、path 和 limit,请查阅插件文档
deploy 用于部署网站。 稍后我们会进行配置

下面我们进行主题的配置,我们可以先在 Hexo 的主题网站中寻找一个自己喜欢的主题:https://hexo.io/themes/

找到之后,点击主题名称,进入主题代码托管的平台,然后将其下载下来,解压在 themes 目录中,主题文件的根目录必须在 themes/<theme-name> 中。

接下来就需要修改主题的配置文件,即主题目录中的 _config.yml 文件。不同主题提供的功能不同,所需要配置的选项也不同,所以请参考所选主题的文档进行操作(一般在主题代码托管的平台就可找到)。

六、如何写文章

Hexo 写作需要使用 Markdown,对 Markdown 不熟悉的读者可以参考:https://www.runoob.com/markdown/md-tutorial.html

Hexo 的文章常用的类别为已发布的文章(Post)和草稿(Draft)。我们在创建文章的时候,两种不同的类别有不同的命令,这两种文章的区别是:

  • 草稿(Draft)的 Markdown 文件存储在项目根目录的 source/_drafts 目录中,在生成网站时不会将草稿包括在内,即草稿不会出现在我们的网站中。
  • 已发布的文章(Post)的 Markdown 文件存储在项目根目录的 source/_posts 目录中,在生成网站的时会将此目录中的所有文章包括在内,即我们可以在网站中看到我们发布的文章。

创建草稿的命令:

1
hexo new draft <title>

创建已发布文章的命令:

1
hexo new post <title>

将草稿发布的命令(将草稿转换为已发布的文章):

1
hexo publish <title>

还有一种文章类型叫做“页面(Page)”,页面是网站中单独的网页,不属于博客文章列表中,不会在首页中显示出来。创建页面的命令为:

1
hexo new page <title>

和上面两种文章类型不同,页面生成后会在 source 目录中创建一个以页面标题命名的文件夹,文件夹里面自动生成一个名为 index.md 的文件,编辑这个文件即可编辑页面的内容。

还记得这个目录是我们克隆下来的吗?编辑好文章内容后,可以将此项目 Push 一下,托管到 Github(处于备份目的)。

七、预览网站效果

写好了自己的文章后,我们就可以在本地进行网站效果的预览了,通过启动本地 Hexo 服务器可以进行预览。

首先安装服务器模块(在 Hexo 项目根目录):

1
npm install hexo-server --save

安装完成后,执行 generate 命令生成网站代码:

1
hexo generate

然后启动服务器:

1
hexo server

然后我们就可以在 http://localhost:4000 这个地址访问我们的网站了。

如果发现需要修改内容,直接修改文件即可,修改完成后不需要重启服务器,更改会自动应用。若启动服务器时发生了 EADDRINUSE(端口被占用)错误,可以使用 -p 参数指定启动端口。

八、部署网站

可以使用 Github Pages 托管自己的网站,如果使用这种方式,请参考文档:https://hexo.io/zh-cn/docs/github-pages

下面要介绍的是通过服务器的部署方式。

首先,我们需要安装 Hexo 的 Git 部署模块,在 Hexo 项目根目录执行:

1
npm install hexo-deployer-git --save

安装完成后,打开项目根目录的 _config.yml 文件,找到 deploy 选项,按照下面的内容进行修改:

1
2
3
4
5
6
7
# Deployment
## Docs: https://hexo.io/docs/deployment.html
deploy:
type: git
repo: <你的github中用来托管网站的项目的ssh地址,即我们上文中创建的Hexo-Website Repository>
branch: master
message: '你想写的提交信息'

这一步告诉 Hexo 我们想要使用 Git 进行部署,且提供了 Git 项目的地址等信息。

然后就可以进行上传了,在根目录执行命令:

1
hexo deploy

等待执行完毕即可。

那么现在就要开始配置服务器了,登录自己的服务器,我以 CentOS 系统为例进行说明。

  • 首先确保服务器中安装了 Git,然后创建一个新用户,这里且命名为 hexo,修改 /etc/passwd 文件授予此用户执行 Bash 脚本的权限。然后我们切换到这个用户:su hexo
  • /var 目录下创建一个新目录,这里命名为 hexo_blog。进入此目录,使用 git 把 Hexo-Website Repository 克隆下来,那么克隆成功后的目录就是 Hexo-Website
  • 安装 Nginx,将 Nginx 的运行用户修改为 hexo(在 /etc/nginx/nginx.conf 中修改)。
  • 配置 nginx.conf,将其 server 块中的内容替换为:
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
listen       80 http2 default_server;
listen [::]:80 http2 default_server;
server_name 你的域名;
root /var/hexo_blog/Hexo-Website;
access_log /var/log/nginx/access-hexo.log;
error_log /var/log/nginx/error-hexo.log;

index index.html index.php;

location = /favicon.ico {
log_not_found off;
access_log off;
}

location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}

location / {
}

location ~ \.php$ {
#NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
include fastcgi.conf;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_intercept_errors on;
fastcgi_pass 127.0.0.1:9000;
}

location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
expires max;
log_not_found off;
}

error_page 404 /404.html;
  • 然后重启 Nginx 即可访问网站(这里我省略了申请域名和配置域名解析的内容)。

接下来,设置自动更新。

  • 首先安装 PHP 运行环境:php-fpm,安装完成后启动,并设置监听端口为 9000.
  • /var/hexo_blog/Hexo-Website 中创建一个目录,命名为 api,创建一个名为 sync.php 的 PHP 文件,内容如下:
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
<?php

// 认证字符串,需要填入Github Webhook Secret中
$code = 'xxxxxxxxxxxxxxxx';

// 测试认证
if (!isset($_GET['code']) || $_GET['code'] !== $code)
{
exit('请提供正确的认证代码。');
}

// 计算Github HMAC认证
$data_body = file_get_contents('php://input');
$hash = hash_hmac('sha1', $data_body, $code);
$hash = 'sha1=' . $hash;
if (!function_exists('getallheaders')) {
function getallheaders() {
foreach ($_SERVER as $name => $value) {
if (substr($name, 0, 5) == 'HTTP_') {
$headers[str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))))] = $value;
}
}
return $headers;
}
}
if (!isset(getallheaders()['X-Hub-Signature']))
{
exit('HMAC认证失败,无签名。');
}
$signature = getallheaders()['X-Hub-Signature'];
if ($hash !== $signature)
{
exit('HMAC认证失败。');
}

$command = 'cd /var/hexo_blog/crontab && nohup ./personal_hexo_blog_hook_sync.sh &';

// 执行更新脚本
system($command, $status);
if ($status)
{
echo '执行失败。';
}
else
{
echo '执行成功。';
}
  • 上面代码中的 xxxxxxxxxxxxxxxx 需要换成你自己指定的认证码(就是随意的一串字符串),这个认证码下面还会用到。
  • 创建目录 /var/hexo_blog/crontab,在其中创建一个名为 personal_hexo_blog_hook_sync.sh 的文件,其内容为:
1
2
3
4
5
6
7
8
9
10
11
#!/bin/bash

# 用于响应Github hook拉取Github的更新

# 记录日志
echo $(date)": Git-Work(Hexo)" >> /var/hexo_blog/git_hook_sync.log

cd /var/hexo_blog/Hexo-Website
git pull >> /var/hexo_blog/git_hook_sync.log

echo "End=====================" >> /var/hexo_blog/git_hook_sync.log
  • personal_hexo_blog_hook_sync.sh 文件加上可执行权限。
  • 编辑 php-fpm 的配置文件,让其以 hexo 用户运行。
  • 重启 php-fpm 服务。

现在,我们的服务器已经配置完成。

我们进入 Github 刚才创建的 Hexo-Website Repository,进入项目的 Settings 选项,点击左侧的 Webhooks,再点击右侧的 Add Webhook 添加新的钩子:

图中,将 你的域名 换成你的域名地址,将 xxxxxxxxxxxxxxxx 换成上文中我们 PHP 代码中设置的认证码,Content type 设置为 application/json,Secret 中也填写相同的认证码,其他的按照图中设置即可。

然后点击 Add Webhook 即可成功添加钩子。

九、测试自动更新

现在我们就有了一个可以自动更新的 Hexo 个人网站了,是不是很简单(bushi)!

我们来测试一下自动更新功能:

  • 修改或者增添一篇博客文章(在本地计算机)。
  • 运行命令(在本地计算机):
1
hexo clean && hexo generate && hexo deploy
  • 等待运行完成,然后再等待大概 2-3 分钟时间让服务器完成更新。
  • 访问你的域名,查看你刚才修改的博客文章是否已经更新了!

要查看 Github 的 Webhook 运行是否正常,进入 Repository 的 Webhook 界面,点击我们添加的 Webhook,往下翻就能看到最近进行过的 Hook 活动了,点击项目就能看到 Github 在执行 Hook 的时候服务器的返回状态码和返回内容,由此判断可能出现的问题。

如上,Body 里返回了 执行成功。 则表明更新成功了。

以上。


使用Hexo搭建可自动同步的个人博客
https://maphical.cn/2020/03/build-blog-using-hexo/
作者
MaphicalYng
发布于
2020年3月26日
许可协议