一直喜欢写文章。大概一年多前吧,在CSDN和javaeye(哦,现在叫做iteye..)注册了帐号,写了几篇博文,但是看着javaeye老土的界面和窄小的编辑区域就没有写的兴致了,CSDN相对大方点,但是速度老慢。还不如我用QQ记事本编辑方便和有意思。想自己写个博客系统,实在是没有抽不出空闲的时间,而且本人前端美工比较烂,所以一直是QQ记事本将就着用。直到最近看到很多人用jekyll搭建了自己的博客系统,所以在这周抽出时间也搞了一个,就是大家现在看到的这个。本博客是在其他文章的帮助搭建成功的,怀着感恩的心,本博的第一篇文章就是详细介绍如何用jekyll搭建一个个人博客。虽然文章很长,但是请相信我,整个过程只需要一天左右。

What: 什么是jekyll

jekyll是一个简洁的、特别针对博客平台的静态网站生成器。它使用一个模板目录作为网站布局的基础框架,并在其上运行Textile 、 Markdown 或 Liquid 标记语言的转换器,最终生成一个完整的静态Web站点,可以被放置在Apache或者你喜欢的其他任何Web服务器上。它同时也是 GitHub Pages 、一个由 GitHub 提供的用于托管项目主页或博客的服务,在后台所运行的引擎。

Why: 为何要使用静态网站生成器(Static Site Generators)?

对于动态内容并非必要的站点——例如个人博客,静态网站生成器这样做有几个明显的优势:

  • 快速访问和弱服务器需求: 静态HTML页面的载入速度理所当然地更快——因为它无需在服务器端执行任何代码,而且天生具有缓存友好性(大部分是302, Not modified.)。同时,这还大大地减轻了服务器的压力。
  • 高安全性: 基于与上述相同的理由,静态页面有着与生俱来的安全性。不像WordPress或者其他任何动态的框架,静态站点本身并不存在安全漏洞的问题。
  • 符合Linux哲学——纯文本,方便利用现有工具: 静态站点的内容完全仅由文件系统中独立的目录和文件构成,没有复杂而不可见的数据库,这意味着你不但可以使用Shell、grep、sed、awk这些传统的Unix工具对它们执行操作和维护,更可以使用 Git 这样的分布式版本控制系统来管理它们,并且享受版本控制所带来的一切好处,如同维护任何软件项目的源代码库一样。你甚至可以重新生成以前任意时间点的整个网站!
  • 简单部署: 一旦静态网站生成以后,任何Web服务器都能够轻易地部署静态站点,而无须在服务器端安装配置其他任何多余的东西。你所需要做的仅仅是通过git、rsync甚至ftp简单地上传文件到你的托管服务器。
  • 文本编辑器和自由格式书写: 也许你不这么认为,但是作为一个hacker而言,在浏览器中一个300x300的文本区里码字写博客并非一件很酷的事情——如果你使用Jekyll这样的静态网站生成器,你就可以用你喜欢的任何文本编辑器(Vim、Emacs、gedit……),用你习惯的标记语言以书写文本文件的方式来直接写博客文章(就好像你平常写代码一样),避免了使用那些简陋和功能有限的Web界面。

但是静态站点也是有缺点的,主要是:

  • 由于静态站点其实是预先动态生成的,而且如果通过github部署的话,我们也没有权限上去直接修改生成的静态文件,所以每次变动都需要在本地修改textile/markdown等文件,用jekyll重新生成,重新提交部署。而jekyll环境需要费一点时间搭建,不过一般我们都是在自己的机器上写博客,所以这是一次阵痛的问题。相比之下,使用数据库的网站,只要有一个能上网的浏览器就可以随时上去修改并立即生效。
  • 由于是静态网站,所以不能有动态控制逻辑,比如权限控制,如设置哪些文章是不公开的,哪些文章在什么时候自动发布,等等。

How

首先要搭建好jekyll环境。

1. 使用RVM安装ruby

安装RVM:<pre class="terminal">$ bash < <(curl -s https://rvm.beginrescueend.com/install/rvm)</pre> 安装ruby1.9.2:<pre class="terminal">rvm install 1.9.2 && rvm use 1.9.2</pre>

2. 使用gem安装jekyll

forrest@forrest-laptop:~$ gem install jekyll
Fetching: liquid-2.3.0.gem (100%)
Fetching: fast-stemmer-1.0.0.gem (100%)
Building native extensions.  This could take a while...
Fetching: classifier-1.3.3.gem (100%)
Fetching: directory_watcher-1.4.1.gem (100%)
Fetching: syntax-1.0.0.gem (100%)
Fetching: maruku-0.6.0.gem (100%)
Fetching: kramdown-0.13.4.gem (100%)
Fetching: posix-spawn-0.3.6.gem (100%)
Building native extensions.  This could take a while...
Fetching: albino-1.3.3.gem (100%)
Fetching: jekyll-0.11.2.gem (100%)
Successfully installed liquid-2.3.0
Successfully installed fast-stemmer-1.0.0
Successfully installed classifier-1.3.3
Successfully installed directory_watcher-1.4.1
Successfully installed syntax-1.0.0
Successfully installed maruku-0.6.0
Successfully installed kramdown-0.13.4
Successfully installed posix-spawn-0.3.6
Successfully installed albino-1.3.3
Successfully installed jekyll-0.11.2
10 gems installed
Installing ri documentation for liquid-2.3.0...
Installing ri documentation for fast-stemmer-1.0.0...
Installing ri documentation for classifier-1.1.3.3...
Installing ri documentation for directory_watcher-1.4.1...
Installing ri documentation for syntax-1.0.0...
Installing ri documentation for maruku-0.6.0...
Couldn't find file to include 'MaRuKu.txt' from lib/maruku.rb
Installing ri documentation for kramdown-0.13.4...
Installing ri documentation for posix-spawn-0.3.6...
Installing ri documentation for albino-1.3.3...
Installing ri documentation for jekyll-0.11.2...
Installing RDoc documentation for liquid-2.3.0...
Installing RDoc documentation for fast-stemmer-1.0.0...
Installing RDoc documentation for classifier-1.3.3...
Installing RDoc documentation for directory_watcher-1.4.1...
Installing RDoc documentation for syntax-1.0.0...
Installing RDoc documentation for maruku-0.6.0...
Couldn't find file to include 'MaRuKu.txt' from lib/maruku.rb
Installing RDoc documentation for kramdown-0.13.4...
Installing RDoc documentation for posix-spawn-0.3.6...
Installing RDoc documentation for albino-1.3.3...
Installing RDoc documentation for jekyll-0.11.2...

3. 使用easy_install安装Pygments用于语法着色和高亮(可选)

1、安装easy_install:

forrest@forrest-laptop:~$ easy_install
The program 'easy_install' is currently not installed.  You can install it by typing:
sudo apt-get install python-setuptools
forrest@forrest-laptop:~$ sudo apt-get install python-setuptools

2、安装pygments:

forrest@forrest-laptop:~$ sudo easy_install Pygments

ubuntu下可以直接apt安装:

forrest@forrest-laptop:~$ sudo apt-get install python-pygments

使用jekyll构建静态博客

现在jekyll的环境已经搭建好了,让我们开始用它来搭建我们的博客吧。 假如你是一个前端比较牛X的人,那么你可以用CSS和JS来控制自己的页面布局和显示效果。否则的话,你也可以像我一样,从github上fork一个你喜欢的,然后稍微修改一下就可以开始写博客了。

关于jekyll的背景知识,在这篇文章 “像黑客一样写博客——Jekyll入门”:http://www.soimort.org/notes/2011/11/19/introduction-to-jekyll_zh.html 有比较详细的介绍,这里就不赘述了。

修改完成之后,你可以使用jekyll --server生成并且测试一下你的网站。 确定没有问题之后,可以git提交到github上,这样,其他人就可以看到你的博客了。 推荐使用这个测试你的jekyll博客,因为他会检测你的文件更改,即时重新增量生成,不需要你手动操作。

部署到github服务器上

本地测试没有问题之后,你可以使用github pages服务,将你的静态网站部署到github上。到github上注册一个帐户,然后按照说明一步一步的执行下去就可以了。具体可以参考这篇文章 “github pages”:http://pages.github.com/ 注意每一步都要做好,否则后面提交会报相应的错误,不过后面根据错误再修改也没有问题的。

域名绑定

github pages默认是以${name}.github.com作为你的虚拟主机域名。假如你有自己的域名,那么可以告诉github,让他绑定你的域名。方法很简单,首先在你的DNS服务商页面增加一条CNAME,让${name}.github.com作为你的一个二级域名,比如blog.arganzheng.me。然后在你的工程中创建一个CNAME文件,告诉github你的真是域名,比如blog.arganzheng.me。这样就可以了。你可以用nslookup查看到你的CNAME的效果:

forrest@forrest-laptop:~$ nslookup 
> blog.arganzheng.me
;; Got SERVFAIL reply from 10.20.0.97, trying next server
;; Got SERVFAIL reply from 10.20.0.98, trying next server
Server:		10.20.0.97
Address:	10.20.0.97#53

\** server can't find blog.arganzheng.me: NXDOMAIN
> server 8.8.8.8
Default server: 8.8.8.8
Address: 8.8.8.8#53
> blog.arganzheng.me
Server:		8.8.8.8
Address:	8.8.8.8#53

Non-authoritative answer:
blog.arganzheng.me	canonical name = arganzheng.github.com.
Name:	arganzheng.github.com
Address: 207.97.227.245

由于我使用的是公司的内部DNS服务器,所以解析不到,可以修改/etc/resolv.conf文件,增加一条nameserver 8.8.8.8 记录。

然后可以用wget blog.arganzheng.me看到整个访问过程:

forrest@forrest-laptop:~$ wget blog.arganzheng.me
\--2012-02-22 10:53:33--  http://blog.arganzheng.me/
Resolving blog.arganzheng.me... 207.97.227.245
Connecting to blog.arganzheng.me|207.97.227.245|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 1526 (1.5K) [text/html]
Saving to: `index.html.1'

100%[===================================================================================================================>] 1,526       --.-K/s   in 0s      

2012-02-22 10:53:34 (89.1 MB/s) - `index.html.1' saved [1526/1526]

forrest@forrest-laptop:~$ wget arganzheng.github.com
\--2012-02-22 10:53:51--  http://arganzheng.github.com/
Resolving arganzheng.github.com... 207.97.227.245
Connecting to arganzheng.github.com|207.97.227.245|:80... connected.
HTTP request sent, awaiting response... 301 Moved Permanently
Location: http://blog.arganzheng.me/ [following]
--2012-02-22 10:54:00--  http://blog.arganzheng.me/
Resolving blog.arganzheng.me... 207.97.227.245
Reusing existing connection to arganzheng.github.com:80.
HTTP request sent, awaiting response... 200 OK
Length: 1526 (1.5K) [text/html]
Saving to: `index.html.2'

100%[===================================================================================================================>] 1,526       --.-K/s   in 0s      

2012-02-22 10:54:00 (91.0 MB/s) - `index.html.2' saved [1526/1526]

可以看到github实际上是做了一个301重定向跳转。而且由于blog.arganzheng.me与arganzheng.github.com作了别名,所以两者解析到同一个IP地址。

参考文章:

–EOF–