博客搭建小结:从wordpress到Hexo+Gitbook

因缘

尽管我在很久之前就打算建立一个个人网站,但因为一直没抽出时间学习基本的html、css、javascript知识、也没理清楚自己到底建这个网站要做什么,这事便一直拖到了上个月,直到我看到腾讯云服务器打折——也就是在一个月前,我购买了一个云服务器,并在上面搭建了wordpress博客(实际上我先在一台试用了15天的服务器上试手搭建了一番)。这一个月的经历记载在了csbook-记录 上了。

之所以选择wordpress还是因为它足够丰富的教程、简洁的后台操作。使用wordpress可以大大减少自己编写代码的苦力劳动,同时也提供了理解前端许多技术栈之间的关系的机会。等到我个人技术达到足够程度时,还可以自己编写php脚本,自定义好看的主题——即所谓“渐进式学习法”。

如果想实现分工合作,就必须设计良好的层次关系,实现组件/模块之间的功能分离:比如wordpress本身是由php实现的,php可以读取数据库、渲染网页、管理用户、调用邮箱服务等等,这些功能都建立在有着良好设计的耦合度上。模块化意味着丰富的拓展性,但同时带来了较高的维护成本——如果我想实现备份与还原数据,就要费力地从头搭建一遍环境,再折腾数据库与插件——这已经背离了我建立个人网站的初衷,我需要消耗大量的精力来维护它的复杂性,要关注每一次更新带来的兼容性问题,还得防范服务器自己出问题,要手动进行多处备份等等。战略性选择中的缺陷必然产生大量无用功,于是再理解了wordpress的基本原理之后,我开始寻找新的博客技术,而Hexo与Gitbook正好出现在我眼前。

Heox 与 GitBook

hexo是基于node.js的博客渲染引擎,gitbook也与之相仿。从功能角度来看,他们就是运行在相应node环境中的markdown转换html的渲染引擎。

首先是markdown语言,这种语言的好处再怎么夸赞都不为过——它提供了一套极为精简的markup语法,可以使用易于理解、记忆的关键字取代富文本编辑器。这意味着它本质上是脱离复杂的编辑器的文件格式,而这种性质必将赋予它强大的生命力——这种将“渲染”功能从富文本编辑器中分离出来的设计正符合了“模块化”的设计思想。

其次就是云备份:好处就是我再也不用担心数据丢失了,尤其是当我同时在两个代码平台上备份源文件时。我只需要担心数据泄露——但目前来说我本身就是要把内容发布出来的,所以这个缺点就完全不成问题了。实际上我认为Git的管理模式并不仅仅局限于编程领域,经过适当的跨领域整合后,它完全可以在许多领域大显身手,尤其是个人文档、笔记的管理——虽然我们已经有了evernote这样的优秀产品,但任何希望拥有个人文档的完全管理权并进行个性化开发、并且不介意折腾的人,不论处在什么行业,都应该了解一下Git的设计思想。

Github、腾讯Coding等云代码托管平台现在基本上都提供有Pages服务。所谓Pages,其实就是静态网页服务——我们在某个项目的某分支(如coding-pages分支)中push网页文件,云平台就会将此分支自动部署到相应域名上了,如GitHub是 userName.github.io/repoName ,coding是 userName.coding.me/repoName ,与域名同名的项目就会成为根页面。如果我们希望使用自己的域名,也可以通过CNAME设置等进行绑定;若是不购买域名,我们就可以白嫖一堆个人网页了~

Docker与持续集成

Hexo与Gitbook虽好,但在使用一段时间后,每次部署时的 cd floderName , hexo g -d 等也都成了种分散注意力的折腾,而且如果我想备份一番的话,重新部署环境也是冷酷的时间杀手。幸运的是这个问题已经有前辈解决了,首先是环境的问题:Go语言的杀手级应用Docker通过将环境打包成mirror,在hub.docker.com上提供了许多实用的镜像环境,我们只需要pull+run就可以在linux种生成相应环境的容器(container),在上面调试自己的程序就可以了。

基于Docker,免费的CI/CD成为可能。所谓CI/CD,实际运用上就是一个在线编译服务器。当我们提交代码更新(push/merge等操作)或进行其他操作时,云代码中心就会通知这个CI服务器,我们定义的脚本就会运行。在脚本里可以定义运行环境,如java/ruby/node等等,这样CI服务器就会在一个Docker容器中运行我们脚本中的script,实现代码的流水线式(pipeline)编译。

GitLab为个人用户提供有一个月2000分钟的免费流水线配额,对大多人来说绰绰有余。即使不够,我们还可以通过在个人主机上搭建 gitlab-ci-runner 实现它的CI功能。使用GitLab的自动集成只需要在项目根目录中编辑 .gitlab-ci.yml 文件,就可以实现我们期望的“手动push,自动部署”操作了。

Coding的CI/CD基于 Jenkins ,需要编辑 Jenkinsfile 。Jenkins比GitlabRunner复杂一些,但插件也更为丰富。Jenkins会在主机上生成一个网页服务器,通过浏览器访问 ip(:8080) 就可以进入Jenkins设置流水线了,这点上Jenkins颇像wordpress。

现状

目前我在 cakipaul.com 域名上的项目都在GitLab上,而 cakipaul.cn 域名上的项目则在Coding上。每个项目通过 .gitlab-ci.yml 文件实现了在GitLab上的自动发布Pages功能,而 Jenkinsfil 则在Coding上发布页面。不过目前为止,由于Coding的pages服务建立在项目分支上,而免费的JenkinsCI又在随机的云服务器Docker上运行,所以没法把渲染好的网页push到coding-pages上。一种解决方法就是在自己的cvm服务器上搭建jenkins,然后使用项目的webhook触发jenkins中的项目;另一种方法就是使用脚本来减少工作量,不过每次脚本还得手动运行。

脚本附录

初始化gitbook的脚本,在/home/node_modules文件夹中放置初始插件,可以在编辑 book.json 文件后通过 gitbook install 生成该文件夹。

clonegb.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#! bin/bash
gitbook=("cs-book" "books" "os" "fe" "java" "cc" "db" "ds" "web" "hw" "mobile" "others")
gitlab="git@gitlab.com:cakipaul/"
coding="git@git.dev.tencent.com:paulsun/"
file="/home/gb/"
mkdir $file

for gb in ${gitbook[@]}
do
mkdir $file$gb
cd $file$gb
git init
git remote add gitlab $gitlab$gb
git remote add coding $codingz$gb
git pull gitlab master
cp -r /home/node_modules /home/gb/$gb/node_modules
gitbook install
done


更新指定hexo/gitbook项目的脚本。

deploy.sh

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
#! bin/bash
#gitbook=("cs-book" "books" "os" "fe" "java" "cc" "db" "ds" "web" "hw" "mobile" "others")
gitlab="git@gitlab.com:cakipaul/"
coding="git@git.dev.tencent.com:paulsun/"
gb_file="/home/gb/" #GitBook项目文件夹的上级目录
hexo_file="/home/" #hexo项目文件夹的上级目录

#选择是hexo还是gitbook项目
echo "hexo/gitbook?(h/g)"

#pull GitLab的项目,更新coding上的master与coding-pages分支;前者是源文件备份,后者作pages页面
read flag
echo "repo's name?"
read repo
if [[ $flag == "g" ]]
then
cd $gb_file$repo
git pull $gitlab$repo master
git push $coding$repo master
#gitbook install
gitbook build . _book
cd _book
git init
git checkout -b coding-pages
git add -A
git commit -m "update coding-pages"
git push -f $coding$repo coding-pages
fi
if [[ $flag == "h" ]]
then
cd $hexo_file$repo
git pull $gitlab$repo master
git push $coding$repo master
hexo g -d
fi


一次性更新全部hexo-gitbook项目的脚本。

update_all.sh

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
#! bin/bash
gitbook=("cs-book" "books" "os" "fe" "java" "cc" "db" "ds" "web" "hw" "mobile" "others")
hexo=("cs-blog" "blog")
gitlab="git@gitlab.com:cakipaul/"
coding="git@git.dev.tencent.com:paulsun/"
gb_file="/home/gb/"
hb_file="/home/"

for gb in ${gitbook[@]}
do
cd $gb_file$gb
git pull $gitlab$gb master
git push $coding$gb master
gitbook build . _book
cd _book
git init
git checkout -b coding-pages
git add -A
git commit -m "Update Coding-Pages"
git push -f $coding$gb coding-pages
done
for hb in ${hexo[@]}
do
cd $hb_file$hb
git pull $gitlab$hb master
git push $coding$hb master
hexo g -d
done