Image by [email protected]

在VPS上通过Jekyll搭建博客

Blog Supported by Jekyll on VPS

  linkthis    2018-03-07    7101 words

本文仅介绍简单的Blog搭建方法,及其相关软件的基础设置,提供一个快速入门的介绍。

Blog类型的选择及前期准备

基于尽量搭建一个便宜简单的Blog的目标,我选择了静态Blog,而不是需要较多资源的动态Blog。而在Jekyll、Hexo、Ghost等静态Blog之中我选择了由Github支持的有较为广泛使用的Jekyll。
在搭建Blog之前我们先要自行准备好一个域名和一台VPS,当然我们也可以直接使用Github Page来搭建Blog,但是为了保证自己能有更大的自主空间我选择了使用VPS,同时也意味着失去了CI等便利的功能。

安装Ruby

Jekyll是基于Ruby写成的,所以我们需要安装Ruby。我们可以选择在Linux或者Windows上安装Ruby,需要注意的是在VPS不一定要安装Ruby,因为Jekyll只是提供一个输出静态内容的功能,而网络服务功能则由其它软件实现。如果需要自己实现类似Github的功能则必须在VPS上安装Ruby。

Linux

选择使用rbenv这个Ruby版本管理工具,将它与ruby-build搭配使用,以实现自动编译安装Ruby、管理多个Ruby版本的目的。
在这里使用的Linux环境为Debian GNU/Linux 9.4 (stretch)

1.安装rbenv及ruby-build
首先安装一些必须的软件:

1
2
apt update
apt install bash-completion curl vim git apt-transport-https libelf-dev socat

rbenvruby-build的源代码均托管在GitHub上,只需通过git命令直接clone到本机即可完成安装。
首先安装rbenv:

1
2
3
4
5
6
git clone https://github.com/rbenv/rbenv.git ~/.rbenv
cd ~/.rbenv && src/configure && make -C src ##编译动态bash扩展以加速rbenv。即使编译失败rbenv也能正常运行(可选操作)
cd ..
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> .bashrc
echo 'eval "$(rbenv init -)"' >> .bashrc
source ~/.bashrc ##使已安装的rbenv在bash中即时生效

安装ruby-build,以便从源代码编译安装Ruby。提供的命令为rbenv install

1
2
mkdir -p "$(rbenv root)"/plugins
git clone https://github.com/rbenv/ruby-build.git "$(rbenv root)"/plugins/ruby-build

安装rbenv-update-rubies,可以升级已安装的Ruby版本(不可以跨大版本升级),升级之后插件会建议卸载过时版本。提供的命令为rbenv update-rubies

1
2
git clone https://github.com/toy/rbenv-whatis.git "$(rbenv root)"/plugins/whatis
git clone https://github.com/toy/rbenv-update-rubies.git "$(rbenv root)"/plugins/update-rubies

安装rbenv-update,以便更新rbenv和全部已安装的插件。提供的命令为rbenv update

1
git clone https://github.com/rkh/rbenv-update.git "$(rbenv root)/plugins/rbenv-update"

执行如下命令检查rbenv的安装配置情况:

1
curl -fsSL https://github.com/rbenv/rbenv-installer/raw/master/bin/rbenv-doctor | bash

2.安装Ruby
在安装Ruby之前,我们还需要准备编译安装Ruby所需的各种工具及依赖。通过如下列命令安装:

1
2
3
sudo apt install autoconf bison build-essential libssl-dev  \
libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev \
libffi-dev libgdbm3 libgdbm-dev

首先执行rbenv install -l获得可安装的Ruby版本列表,之后执行:

1
rbenv install 2.4.3

如果需要多版本,重复进行安装即可。

3.Ruby版本管理
rbenv 支持以下三种 Ruby 版本的环境管理:

  • global:设置全局的 Ruby 版本,换句话说,所有的 shell 都将使用该 Ruby 版本。
  • local:为本地的一个特定项目设置 Ruby 版本,注意这将覆盖全局设置。
  • shell:针对 shell 设置 Ruby 版本,该设置将覆盖 global 和 local 设置。

通过rbenv versions可以列出rbenv已知的所有Ruby版本,并在当前活动版本号旁边显示星号;而rbenv version只会列出当前激活的版本以其设置信息。
而要将之前安装的Ruby 2.4.3设置为全局性版本,应该执行:

1
rbenv global 2.4.3

Windows

在Window系统中,我们可以使用RubyInstaller或者Windows Subsystem for Linux(WSL)来安装Ruby环境。
在WSL中安装rbenv的操作与Linux下相同,只是在WSL下Jekyll的Auto-regeneration可能无法正常工作,而且WSL的版本不能过低,否则Jekyll可能无法正常运行。
RubyInstaller可以在此界面下载。在安装过程中,一定要勾选Add Ruby executables to your PATH,以便在CMD当中使用Ruby。需要注意的是,从Ruby 2.4.0开始,MSYS2 toolkit成为了官方开发工具,为了使用Ruby gems我们应该根据安装程序的引导安装MSYS2。

安装Nginx

选择使用轻量的Nginx作为Web Serve。由于各个发行版中提供的Nginx版本落后,所以选择从Nginx官方提供的源当中进行安装。
首先编辑/etc/apt/sources.list添加Nginx官方预编译源:

1
2
3
4
5
6
## 稳定版
deb http://nginx.org/packages/debian/ stretch nginx
deb-src http://nginx.org/packages/debian/ stretch nginx
## 主线版(含有所有模块)
deb http://nginx.org/packages/mainline/debian/ stretch nginx
deb-src http://nginx.org/packages/mainline/debian/ stretch nginx

现在由Nginx提供的Debian版本如下:

系统版本 Codename 支持平台
8.x jessie x86_64,i386
9.x stretch x86_64,i386

添加Nginx官方源的密钥避免安装时出现警告:

1
2
wget https://nginx.org/keys/nginx_signing.key
apt-key add nginx_signing.key

更新源并安装和启动Nginx:

1
2
3
apt update
apt install nginx
service nginx start

此时执行service nginx status应该返回[ ok ] nginx is running
之后创建一个简单的Nginx配置文件:

1
2
3
4
5
6
7
8
vi /etc/nginx/sites-enabled/default
## 修改为以下配置
server {
  listen 80;
  server_name example.com;
  root /var/www/my-awesome-site;
  index index.html
}

保存之后执行nginx -s reload重新载入配置文件。此时通过域名应该可以访问Blog了。

Acme.sh

为了提高网站的安全性和保证访问质量,我们需要让网站使用HTTPS连接,而我们首先需要申请一个受信任的证书。大牌提供商的SSL证书并不便宜,所以我们选择使用由Let’s Encrypt提供的免费证书。需要注意的是Let’s Encrypt提供的证书的有效期只有90天,所以我们需要使用脚本定期更新。而acme.sh实现了acme协议,可以从Let’s Encrypt生成免费的证书并自动更新。

ACME的全称为Automated Certificate Management Environment,即自动化证书管理环境,相关内容可以参看此仓库

安装acme.sh十分简单,只需执行如下命令:

1
curl  https://get.acme.sh | sh

其会安装到所在目录下的~/.acme.sh/中,并自动创建一个bashaliasacme.sh=~/.acme.sh/acme.sh。注意为了让安装在shell当中即时生效,我们需要执行:source .bashrc。安装过程不会污染任何已有的系统功能和文件, 所有的修改都限制在安装目录:~/.acme.sh/中。如果需要更高级的安装选项可以参看acme.shHow to install
acme.sh提供的验证方式当中我们选择使用DNS验证(不需要任何服务器和任何公网IP,只需要DNS的解析记录即可),不过我们需要同时配置Automatic DNS API,保证acme.sh自动更新证书。在此仅以Cloudflare为例,执行如下操作:

1
2
3
export CF_Key="sdfsdfsdfljlbjkljlkjsdfoiwje"
export CF_Email="[email protected]"
acme.sh --issue  --ocsp-must-staple --dns dns_cf -d example.com -d *.example.com

配置当中需要等待300s以便自动添加的txt解析记录生效。Cloudflare的API可以在My profile内找到,配置的CF_KeyCF_Email将被存储在~/.acme.sh/account.conf
其它域名商API的用法可以参看DNS API
由于acme协议和Let’s Encrypt CA都在不定期的更新, 因此acme.sh也需要更新以保持同步,执行如下命令:

1
2
3
acme.sh --upgrade #手动更新
acme.sh  --upgrade  --auto-upgrade #自动更新
acme.sh --upgrade  --auto-upgrade  0 #关闭自动更新

HTTPS

在为Nginx配置HTTPS之前,我们首先需要将刚才申请的证书安装到需要使用的地方,请不要使用~/.acme.sh/目录下的文件,里面的文件都是内部使用,而且目录结构可能会变化。首先应该创建存放使用证书的文件夹:

1
mkdir /etc/nginx/ssl/

然后使用--installcert将证书安装到指定位置:

1
2
3
4
acme.sh --install-cert -d example.com \
--keypath       /etc/nginx/ssl/mydomain.key  \
--fullchainpath /etc/nginx/ssl/fullchain.cer \
--reloadcmd     "service nginx force-reload"

需要指定--installcertreloadcmd保证证书更新以后自动调用新的证书给Nginx使用。同时我们使用的是fullchain.cer,防止SSL Labs测试时出现Chain issues Incomplete的错误。而Nginx应该使用force-reload保证重新加载证书。更加详细的参数可以参考Install the cert to Apache/Nginx etc
如果出现Failed to restart nginx.service: Unit nginx.service is masked.,则需要先执行:

1
systemctl unmask nginx

然后生成键值以启用Perfect Forward Security(PFS):

1
openssl dhparam -out dhparam.pem 4096

之后进行HTTPS配置的环境为:Nginx 1.13.10,OpenSSL 1.0.2l,支持HSTS。 你可以使用如下命令查看Nginx和Openssl的版本:

1
2
nginx -v
openssl version

Nginx配置模板:

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
server {
    listen 80 default_server;
    listen [::]:80 default_server;

    # 使用301将HTTP访问重定向到HTTPS
    return 301 https://$host$request_uri;
}
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    access_log  /var/log/nginx/www.mydomain.com_access.log;
    error_log  /var/log/nginx/www.mydomain.com_error.log;

    # Let's Encrypt生成的文件
    ssl_certificate /etc/nginx/ssl/fullchain.cer;
    ssl_certificate_key /etc/nginx/ssl/<domain>.key;
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:50m;
    ssl_session_tickets off;

    ssl_dhparam /etc/nginx/ssl/dhparam.pem;

    # OCSP Stapling ---
    # fetch OCSP records from URL in ssl_certificate and cache them
    ssl_stapling on;
    ssl_stapling_verify on;

    ssl_protocols TLSv1.2;
    ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';
    ssl_prefer_server_ciphers on;
}

在浏览器打开http://www.mydomain.com,如果正常跳转到https://demo.mydomain.com,说明HTTPS配置成功。
你还可以使用SSL Labs测试自己网站的HTTPS配置。使用如下命令查看证书过期时间:

1
openssl x509 -noout -dates -in /etc/nginx/ssl/<domain>.key

Jekyll使用

首先安装Jekyll:

1
2
3
gem install jekyll bundle
jekyll new my-awesome-site
cd my-awesome-site

这样就完成了Jekyll的安装,并且使用了Jekyll自带的主题。不过为了使Blog有更好的效果,我们通常会使用自己编写的主题或者由他人提供的主题。在此仅列举几个主题网站和较好的主题:

在下载这些模板之后,根据README和注释进行修改,也可以根据自己的需求进行修改,即可快速完成Blog的搭建,需要注意的是,如果主题当中使用了Jekyll插件,需要通过Gem自行安装以达到主题Demo相同的效果。
在将自己的文章添加到_post之后执行jekyll serve,然后访问http://127.0.0.1:4000就可以实现本地预览。在完成调试之后执行如下命令生成静态Blog:

1
jekyll build --source /home/my-awesome-site --destination /var/www/my-awesome-site

至此你的个人Blog就完成了搭建。
如果需要使用Cloudflare作为CDN可以参看我之前的文章:Cloudflare使用记录

关于Git设置等操作日后再补。
本文采用CC BY-NC-ND 4.0许可协议进行许可,转载请注明出处。

本文最后更新时间为:2019-05-26-Sunday-01:05:01 PM




Image of Wechat