0%

从 Wordpress 迁移到 Hexo

写在最前面的话

大概从 03 年开始接触博客到现在,已有十多年。早期换过无数的 BSP,比如 Blogbus、Live Space、百度空间、Blogger 等;也通过自建服务的方式,搭建过 Wordpress。由于这样那样可抗或不可抗的缘由,搬家无数次,用过第三方服务、免费虚拟主机、合租虚拟主机、VPS。遭遇过各种域名、主机事故,比如被封、被黑、服务中断等,本博客却从未中断,主要内容也通过一次次的迁移得以延续。能延续这么久(虽然最近一些年,由于自己懒,长时间处于半停滞状态),个人感觉最重要的一点在于,购买了博客专用的顶级域名 interjc.net,这个域名伴随了各个时期不同形态的本博客,也延续了与博友和读者之间的羁绊。

自从东哥的虚拟主机服务关停以后,本博客就一直托管在 Vultr VPS 上,速度和稳定性都还 OK,并且由于是 VPS,还通过 Let’s encrypted 启用了 https,整个使用还是比较平滑的。

契机

虽然 WordpressHexo 都是比较优秀的 CMS 系统,所以在此不讨论他们孰优孰劣的问题。他们之间的区别是显而易见的: Wordpress 是一个相对较重的 CMS 平台,所有的数据保存在 MySQL 数据库中,需要在一个支持 PHP 的环境中运行;Hexo 所有的数据都保存在文件中,通过预编译输出为静态文件,可以托管于任何一个静态文件服务器(基于 Nginx、Apache、IIS 等)中。

Hexo 像极了早期的 Blogger 自托管模式,每一次你修改了博客中的任何东西,他都需要重新编译所有的内容为新的静态文件,并且需要发布到静态文件服务器中。对于早年的我来说,博客配置、主题的修改和文章的发布、维护相当频繁,自然是无法忍受 Blogger 系统极慢的发布速度,所以后来一鼓作气搬到了 Wordpress。

但是时过境迁,作为一个连博文都懒得时常更新的人,更不会不停修改自己的博客主题了,并且当下各种本地或在线的工具链,都使得发布过程自动化成为了可能,即便是使用 Hexo 这种预编译的方案,也可以使博主只需要专注于博客内容本身。基于此,Wordpress 的优越性逐渐显得荡然无存,臃肿的系统占用着 VPS 资源,如果再配上一个大半年都不更新的博主,也是够浪费资源的。

需求

博客搬家毕竟是麻烦事,各种迁移和设置,所以在实施之前,认真思考了一下自己的需求,做了一个可行性调研。新的博客需要满足:

  • 支持 HTTPS
  • 可以绑定独立域名
  • 旧的博客文章可以方便地迁移
  • 尽可能方便的文章发布流程
  • 博客系统高度自主可控
  • 服务器稳定
  • 墙内可访问
  • 尽可能轻量级

方案

说干就干,通过将 Hexo 部署到 Github 上,使用 Github 的 Action 做 CI/CD,完美实现了以上所有的需求。你现在看到的本博客正是基于上述方案搭建的。整个迁移过程经历了以下步骤,我将逐个讲解:

从旧博客导出 Wordpress 文件

其实这一步是比较简单的,在 Wordpress 后台界面,选择 工具 -> 导出,将导出的 xml 文件保存在本地,命名为 wordpress.xml

Github 仓库创建、博客项目初始化

我们将创建两个 Github 仓库,一个用于放置博客程序本体,另一个用于发布博客静态页面,按如下要求配置:

用途 仓库名 仓库类型
博客程序 blog Private
静态文件 weblog Public

本地 Hexo 系统初始化,并导入 Wordpress 数据

安装 Hexo

参考 Hexo 官方手册,先安装 hexo-cli

1
npm install -g hexo-cli

再使用 hexo-cli 在本地创建 hexo 工程

1
2
3
cd ~/path/to/workspace # 此处使用 cd 命令定位到相应目录
hexo init blog
cd blog && npm install
导入 Wordpress 数据

参考官方迁移文档,先安装 hexo-migrator-wordpress 插件,然后导入之前步骤中下载的 wordpress 导出文件:

1
2
npm install hexo-migrator-wordpress --save
hexo migrate wordpress ~/path/to/wordpress.xml # ~/path/to/wordpress.xml 替换为真实路径
同步到 Github 仓库

在上述创建的 blog 仓库,找到 Clone or Download 按钮,复制命令并在本地命令行工具中执行,形如: https://github.com/yourname/blog.git

在本地 blog 目录,执行以下命令 (参考),将 hexo 主程序代码上传到 Github 上的 blog 仓库:

1
2
3
4
cd ~/path/to/workspace/blog
git init
git remote add origin https://github.com/yourname/blog.git
git push -f

此处操作,未接触过 git 的朋友,建议学习一下 git 相关操作后进行,或者使用 SourceTree 等可视化工具。

主题设置

你可以使用默认主题,也可以使用主流第三方主题,比如 Next,具体配置方法自行查看:

https://theme-next.org/docs/getting-started/

构建和发布

无论我们是否需要自动化构建和发布,都需要在本地尝试发布静态博客,把这个步骤走通以后,再进行后续的高阶设置。

修改 Hexo 设置

_config.yml 文件中,搜索 deploy,修改为 weblog 对应的仓库:

1
2
3
4
deploy:
- type: git
repo: [email protected]:yourname/weblog.git # yourname 替换为你的 github 真实用户名
branch: gh-pages
安装发布插件
1
npm install hexo-deployer-git --save
构建并发布
1
hexo g -d
查看发布状态

此时我们打开 github.com/yourname/weblog/settings 的仓库配置页面,找到 GitHub Pages 这一栏,你会找到一个相应的访问地址,那就是你的博客地址了,形如(参考):

至此,你已经完成了最基本的迁移,如果需要绑定域名,只需要填下下面的 Custom Domain 信息即可。

需要注意的是,当你绑定域名时需要做一些其他的关联操作,这个将在下面的专门章节中讲解

域名绑定

如果需要为 weblog 仓库上的页面添加独立域名,可以参考 Github 官方手册,主要关注以下链接:

按照官网所说的步骤设置即可,Github 会自动往仓库里添加一个名为 CNAME 的文件,由于 Hexo 每次构建时,都会删除所有的静态文件,所以我们需要将此文件原样拷贝到本地 blog 程序下的 source 目录中。

当域名审核完毕后,就可以勾选 Enforce HTTPS 复选框。至此,整个博客的迁移工作也就已经基本完成了。

自动化构建和发布

添加秘钥对

打开命令行提示符,输入如下命令,创建秘钥对(如果是 Windows 电脑需要用 ssh-keygen 命令生成一组私钥和公钥):

1
ssh-keygen -f blog-deploy-key # 无脑回车

产生如下文件:

  • blog-deploy-key (私钥)
  • blog-deploy-key.pub (公钥)

在 Github 仓库中,做如下操作:

  • 在 weblog 仓库中,点击 settings -> Deploy keys -> Add deploy key,填写 nameblog-deploy-key.pub, value公钥 (blog-deploy-key.pub) 中所有的文本内容(可以用 vscode、sublime 等文本编辑器打开)
  • 在 blog 仓库中,点击 settings -> Deploy keys -> Add deploy key,填写 nameHEXO_DEPLOY_PRI, value私钥 (blog-deploy-key) 中所有的文本内容
配置持续集成/发布(CI/CD)

在 blog 仓库中,点击 Actions -> New Workflow -> Set up a workflow yourself,输入文件内容如下:

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
50
51
52
53
# This is a basic workflow to help you get started with Actions

name: Publish latest blog

# Controls when the action will run. Triggers the workflow on push or pull request
# events but only for the master branch
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [16.*]

steps:
- uses: actions/checkout@v1

- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}

# 注意将 user.email 修改为你自己的
- name: Configuration environment
env:
HEXO_DEPLOY_PRI: ${{secrets.HEXO_DEPLOY_PRI}}
run: |
mkdir -p ~/.ssh/
echo "$HEXO_DEPLOY_PRI" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
ssh-keyscan github.com >> ~/.ssh/known_hosts
git config --global user.name "Blog CI Action"
git config --global user.email "[email protected]"

- name: Install dependencies
run: |
npm i -g hexo-cli
npm ci

- name: Publish hexo
run: |
npm run publish

# 这一步的主要目的是向百度站长 API 提交链接,如果有需要再取消注释
# - name: Submit to baidu
# run: |
# bash submit.sh
完成 CICD 参考

至此,你每一次同步 blog 仓库的代码到 github 都会触发 CICD actions,博客就会自动构建发布了。盗一张阮一峰的图给大家看看构建过程的 log 长啥样:

更多高阶玩法可以查看阮一峰的 Github Actions 入门教程

SEO

先安装和配置以下这几个插件:

时间有限暂时先不详细的说这部分内容了,先放出 CI/CD 这一步中缺失的 submit.sh 源码:

1
2
3
4
5
6
7
8
#!/bin/bash

# Generate sitemap.txt
sed -n 's:.*<loc>\(.*\)</loc>.*:\1:p' ./public/baidusitemap.xml > ./public/sitemap.txt

# submit to baidu
# 在 https://ziyuan.baidu.com/linksubmit 中获取相关 token
curl -H 'Content-Type:text/plain' --data-binary @public/sitemap.txt "http://data.zz.baidu.com/urls?site=https://interjc.net&token=your_baidu_token"

欢迎关注我的其它发布渠道