基于Jekyll的博客系统


Jekyll其实大家用了很久了,以前我在“自豪地采用Wordpress”,但世界上最好的语言DO $5的plan是实在是跑不起,最近忍无可忍才更换,也顺便换了L家更贵的plan,当然速度也快不少。一些使用心得和注意事项,供比我还后来的人参考。

简介

Jekyll不同于以前用的CMS,它只是一个静态网站生成器 - 但这对于一个博客已经够用了,相比之下CMS对于博客来说太重了。所以Jekyll的优点就是简单,没有数据库,什么都没有。就是你写md,然后它帮你生成html,放到你配置的URL路径对应的path而已。

Jekyll支持一种叫liquid的模板语言,正是靠它通过模板生成了一整个site,很简单的syntax,默认已经选择了minima主题,参考它已有的框架,很简单上手。

没有服务器,怎么发表文章?怎么鉴权?Git作为一种分散式版本管理系统再合适不过,和Jekyll是天造地合,随时随地都可以pull下来添加文章。想要换一个地方部署,只要clone一下。再也不怕转移起来麻烦了。。。

安装

安装中可能遇到的坑: - 执行build时可能说缺少json这个gem,加到Gemfile里,重新bundle install即可 - 用于--watch参数监视fs change自动build的库用到libffi,不知道为什么装了libffi-devel, libffi-static,配了path,ffi的gem即使编译过了在运行时也会报找不到libffi的错,CentOS 7有这个问题,但很少在CentOS 7上写blog和实时review,所以也不需要watch,指定—no-watch即可

基于Github Pages的部署

一开始我使用Github Pages来部署,连自己的server都不用了,还支持自定域名,很好很强大。只需要建一个{用户名}.github.io的repo,然后推上去,Github会自动build。_site这个目录是Jekyll输出build结果的地方,github会帮你build,所以可以放进.gitignore。

为了引入分页,使用了jekyll-paginate plugin,Github Pages支持的gem plugin是有限的,但我有看到jekyll-paginate是支持的,只是不work,还有一些看起来和本地build出来不一样的奇奇怪怪的问题,所以我今晚还是放到我自己的server上部署了,反正都买了,带宽闲着也是闲着。。。如果使用gh,用Jekyll plugin可以这里先查查是否支持。

如果实在不支持又想用Github Pages,没关系啊,Jekyll就是个静态站嘛,本地build好,把刚才说的_site目录推上去,不给他们build就好了呗。

基于自己server的部署 - 使用git hooks

刚才说到两个是用Github Pages的约束:有限的plugin支持,build的结果可能有差异但是却不能debug。所以还是在自己的server上可控一点。

在自己server上也能实现如Github Pages的功能,你只需要push一下,remote就会自动build好,无需先推到central server,然后再ssh上server,再拉下来build。。。只需要自建git repo使用git hooks即可,下面是个官网提供的例子,我做下注释。

需要用到三个文件夹,一个是用来做repo的,即下面的myrepo.git;由于repo里面存的是object,我们需要再在一个临时文件夹,即下面的$HOME/tmp/myrepo,clone到这个文件夹还原成目录方便进行下一步;还有一个放build结果,即对外访问的要写进nginx配置的文件夹,下面是/var/www/myrepo

laptop$ ssh deployer@example.com
server$ mkdir myrepo.git
server$ cd myrepo.git
server$ git --bare init
server$ cp hooks/post-receive.sample hooks/post-receive
server$ mkdir /var/www/myrepo

可能有的git版本没有hooks/post-receive.sample这个文件,但这个hook还是有的,不拷贝而是新建一个post-receive文件即可,然后即可将下面几行加入myrepo.git/hooks/post-receive

GIT_REPO=$HOME/myrepo.git
TMP_GIT_CLONE=$HOME/tmp/myrepo
PUBLIC_WWW=/var/www/myrepo

git clone $GIT_REPO $TMP_GIT_CLONE
jekyll build -s $TMP_GIT_CLONE -d $PUBLIC_WWW
rm -Rf $TMP_GIT_CLONE
exit

这样server 端就准备好了,在本地添加server上的repo,再push的时候就会生效了:

laptops$ git remote add deploy deployer@example.com:~/myrepo.git
laptops$ git push deploy master

需要注意的是,如上边说的,如果你是自己建的post-receive这个文件,要记得chmod给它一个可执行权限,不然是不会执行这个hook的,我server上的git版本1.8.3.1就这个问题。

另外要注意权限问题,三个文件夹该用户都要有权限写。

在remote add这一步,如果SSH使用了不标准端口怎么办?可以显式使用协议地址:

git remote add deploy ssh://deploy@example.com:{port}/~/myrepo.git

可能的优化

二进制文件放进git是大忌,所以将来可能会将照片移出repo,放在一个单独的http服务。

对Ruby不熟悉,用起来还是觉得悬,所以,最大的优化恐怕是有时间自己写个webapp和REST API做博客啦 XD。