在VPS上建立了Hexo博客

因缘际会之下,我建立了这个yicong2007’s blog.

购买VPS

搬瓦工(BandwagonHOST)上线CN2 GIA线路后,总在种草,最近居然缺货了,幸好看到通过升级方案的方法购买搬瓦工CN2 GIA便宜方案,在该方案还有效的时间内购买了搬瓦工CN2 GIA最便宜套餐的VPS。
这个VPS本来是考虑给上网加速多一条快速的线路(你懂的),但平时总是要把它用起来,于是考虑干脆在平常把它做成一个blog。

配置域名及HTTPS

购买域名

要实现某些情况下的TLS,需要一个域名。为了免备案(而且VPS本身是放在国外),我到Namecheap购买了yc2007.xyz这个域名。

配置SSL证书

现在很多人采用Let’s encrypt的免费SSL证书,而且现在有通配符证书。但缺点是三个月一签,如果忘了重签,三个月后就会失效,虽然可以在VPS上自动设置定时任务来重签。由于我在Namecheap购买域名时,Namecheap提供了首年以$1.99的优惠价格购买Comodo的PositiveSSL单域名证书,所以我直接选择使用这个证书。
在VPS上安装nginx后使用openssl命令就可以生成证书所需的KEY文件和CSR文件。

1
2
$ openssl ecparam -genkey -name secp256r1 -out yc2007.xyz-ecc.key
$ openssl req -new -sha256 -key yc2007.xyz-ecc.key -out yc2007.xyz-ecc.csr

证书签名类型我选择了ECC,因为我不用太考虑客户端环境向下兼容性的问题。将CSR和KEY的内容复制粘贴到证书生成页面,再选择合适的验证方式来验证我是域名的拥有者(这里我选择了DNS解析的方式,在DNS解析记录上加入所要求的CNAME记录,等待Comodo验证成功),就可以收到Comodo签发的证书。在nginx的配置文件中做设定,就可以对443端口启用SSL证书。
PositiveSS

建立博客

在查找VPS配置的过程中,发现不少人使用Hexo来做博客,看起来确实舒服,于是就准备用它了。

安装Hexo

这段本来没什么好说的,但要注意Hexo官网文档中给出的安装nvm的命令:

1
$ curl https://raw.github.com/creationix/nvm/master/install.sh | sh

其中的install.sh脚本的github地址形式是过时的,因为github改了地址域名,在nvm的github页面中提供了正确的命令:

1
$ curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh | bash

其中v0.33.11版本号应该会随着更新而改变,所以安装时应到nvm的github页面中去重新确认。

注意如果准备好要通过git来部署Hexo,则最好先在VPS上安装git,然后增加git用户,切换到git用户后再进行node.jsHexo的安装。因为nvm的默认安装路径的环境变量$NVM_DIR是设置为$HOME/.nvm的,我之前没注意,在root下先安装了nvmnode.jsHexo,都跑完hexo g了,才去看如何使用git进行部署,结果切换到git用户发现还得再在git的$HOME/.nvm下把nvmnode.jsHexo再安装一次,才能在git用户下使用。

综上,安装完git之后,添加git用户并切换到该用户,运行以下命令可安装Hexo:

1
2
3
4
$ curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh | bash
$ nvm install stable # 执行完这个命令行,要打开一个新Shell,以使新的环境变量在新Shell里起效,再在新的Shell里面输入下面的命令
$ npm install -g hexo-cli
$ npm install hexo-deployer-git --save

VPS上自建远程仓库,实现通过git进行部署

通常情况下,特别是把Hexo部署在github上时,大家基本上采用的是在本地客户端安装Hexo环境,然后使用hexo deploy命令,配合在VPS上建远程仓库的git hooks功能(指定post-receive脚本),将静态文件上传到VPS后实现自动部署。

而我却是先直接在VPS上安装了Hexo环境生成了hello-world.md。思前想后,我还是保留VPS上的Hexo环境(这样我可以直接登录VPS去部署,特别是如果我有机会在iPad上写Markdown的情况下,本地可以没有Hexo环境,通过登录VPS,上传.md文件之后运行命令直接部署),另在本地macOS上安装了Hexo环境。

另外还有一点,hexo deploy命令只是把hexo generate后生成的静态文件(public目录)push到远程仓库完成部署(这个功能是跟使用github做网站直接相关的,使用它可以默认将Hexo博客内容直接部署到托管在github上的网站),但是Hexo的配置、源文件和主题等也需要使用git进行版本控制和备份。所以hexo deploy所对应的git远程仓库源,和备份同步Hexo的配置、源文件和主题等使用的远程仓库源,是不一样的。这两者可以使用两个不同的repos,也可以使用同一个repo的不同branches来实现(如果使用github托管,则要求博客静态文件内容必须部署到master分支)。这里我虽然是自己用VPS来做,但是因为是git的新手,为了避免切换不同分支可能出现的问题,特别是希望post-receive脚本不需要去区分是对哪个分支的推送,所以我还是建了两个远程仓库来实现分别接收静态文件和Hexo源文件的更新。

前置准备工作(git用户SSH使用密钥登录VPS)

安装git之后,先添加git用户,设置好密码。

然后设置好从本地以git用户身份连到VPS的SSH公钥:
在本地配置:

1
$ ssh-keygen -t rsa

生成$HOME/.ssh/id_rsa$HOME/.ssh/id_rsa.pub,后者是公钥。
因为VPS的SSH端口一般都不是默认的22,最好修改本地的$HOME/.ssh/config文件,加入VPS的SSH登录配置信息:

1
2
3
4
5
Host [your_vps_IP_or_domain_name]
HostName [Custom_Name]
User git
Port [SSH_Port_in_Your_VPS]
IdentityFile ~/.ssh/id_rsa

将本地生成的id_rsa.pub的内容,复制到VPS上git用户的$HOME/.ssh/authorized_keys文件中,并注意:

  1. $HOME/.ssh目录和authorized_keys文件的owner必须是git用户自己;
  2. $HOME/.ssh目录其权限设置必须是700(即只有git用户自己可以读写执行,其他用户无法读写);
  3. $HOME/.ssh/authorized_keys文件其权限设置必须是600(即只有git用户自己可以读写,其他用户无法读写)。

必须设置好以上三点,否则公钥登录无法生效。
设置好VPS的/etc/ssh/sshd_config文件,打开以下选项(取消注释):

1
2
3
RSAAuthentication yes
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys

然后以root用户身份重启SSHD服务:

1
# service sshd restart

配置完成后,只要在本地使用

1
$ ssh git@[Custom_Name]

能直接登录VPS,就说明配置成功了。

远程服务器上配置远程仓库

建立远程仓库(裸仓库),对静态文件仓库,设置好post-receive,使之可以自动部署到blog的根目录:

1
2
3
4
5
6
7
8
9
10
$ su git
$ mkdir /path/to/hexo.git #源文件远程仓库
$ mkdir /path/to/hexo_public.git #静态文件发布远程仓库
$ mkdir /path/to/www/html #网站blog根目录
$ cd /path/to/hexo.git
$ git init --bare
$ cd /path/to/hexo_public.git
$ git init --bare
$ cd hooks
$ touch post-receive

在post-receive文件中写入如下代码(这里我选择了简单粗暴的方法,这样似乎更容易让web服务器及时更新)

1
2
3
4
5
6
7
8
9
#!/bin/bash
REPO_DIR=/path/to/hexo_public.git
TMP_DIR=/path/to/hexo_public_tmp
DST_DIR=/path/to/www/html
rm -rf $TMP_DIR
git clone $REPO_DIR $TMP_DIR
rm -rf $DST_DIR/*
cp -rf $TMP_DIR/* $DST_DIR
rm -rf $TMP_DIR

另外一种写法是:

1
2
#!/bin/bash
git --work-tree=/path/to/www/html --git-dir=/path/to/hexo_public.git checkout -f

然后设置post-receive为可执行:

1
$ chmod a+x post-receive

这样一旦接到推送,VPS上的/path/to/www/html目录就会自动被更新。

“本地”仓库建立并第一次推送源文件到远程仓库

“本地”仓库是源文件用的仓库,可以是在本地客户端,也可以在远程VPS上放一个。以下命令都是在“本地”操作。

方法1(推荐):先生成空的远程裸仓库,clone到本地,再初始化Hexo目录

这样做相对来说最顺畅。

先将空的远程裸仓库的内容git clone到“本地”仓库:

1
$ git clone git@[Custom_Name]:/path/to/hexo.git /path/to/local/hexo/

其中/path/to/local/hexo/为“本地”仓库目录。这时“本地”仓库还是空的,然后再初始化Hexo目录:

1
2
3
$ cd /path/to/local/hexo/
$ hexo init
$ npm install

Hexo目录在本地初始化之后,再进行安装主题等操作,并修改 _config.yml文件写入自己的设置,其中必须写好部署的配置:

1
2
3
4
deploy:
type: git
repo: git@[Custom_Name]:/path/to/hexo_public.git
branch: master

然后生成静态文件(这个过程中也验证配置正不正确):

1
2
$ hexo clean
$ hexo g

如果能正常执行命令生成文件,说明配置至少形式上没问题。

然后再做git设置:

1
2
3
4
5
$ cd /path/to/local/hexo/
$ git add -A
$ git config user.name [Your_User_Name] #如之前已设置过全局的git用户信息,也可以直接用,不用此命令;如果之前未设置过全局的git用户信息,则先git config --global设置一下。但无论如何,这个命令可以设置本项目单独的用户信息。
$ git config user.email [Your_Email]
$ git commit -m "First commit"

至此才终于完成了本地源文件git仓库的初始源代码提交。然后就可以直接push了:

1
$ git push origin master

以上命令向远程仓库hexo.git的master分支推送源文件及设置。因为hexo initHexo已经生成了.gitignore,那些public目录中的静态文件是不会被推送的。

方法2:把已存在的Hexo目录变成git本地仓库,再实现推送和部署

我的情况是我已经在VPS上用hexo init建了一个目录,已经hexo g了。那就不是从零开始了。
一种方式是仍然使用git clone从远程仓库克隆下来一个空的“本地”仓库,然后把原来的Hexo目录中的文件全搬过去,然后跳过方法1中初始化Hexo目录的步骤,直接编辑_config.yml写入部署设置,然后同样执行git add -Agit commitgit push三连,以及hexo d,实现推送和部署。
另一种方法是不先从远程仓库clone下来,而是先编辑_config.yml写入部署设置并hexo g完成后,要把这个“本地目录”变成git的本地仓库,然后commit并push到远程仓库。相应命令如下:

1
2
3
4
5
6
7
8
$ cd /path/to/local/hexo/
$ git init #初始化为git本地仓库
$ git remote add origin git@[Custom_Name]:/path/to/hexo.git #要自己跟远程仓库关联起来
$ git add -A
$ git config user.name [Your_User_Name] #如之前已设置过全局的git用户信息,也可以直接用,不用此命令;如果之前未设置过全局的git用户信息,则先git config --global设置一下。但无论如何,这个命令可以设置本项目单独的用户信息。
$ git config user.email [Your_Email]
$ git commit -m "First commit"
$ git push --set-upstream origin master #尚未创建分支的情况下,第一次要set-upstream指定上传的分支,以后就直接git push origin就可以。

后续更新和博客部署

以后每次更新时(包括从多个本地仓库更新时),只需要先git pull把远程仓库的文件拉下来,修改文件之后hexo g生成,然后运行git add -Agit commitgit push三连,就可以把源文件推送到远程仓库。
注意:建议先使用hexo g生成成功之后,再git commit,以防因为配置写错,先commit了一个有bug的无效版本。

只要前面的远程仓库的配置和本地_config.yml的设置好了,就可以用Hexo的部署功能推送静态文件:

1
$ hexo d

以上命令就可以实现把静态文件内容直接通过远程hexo_public.git仓库部署到VPS上的/path/to/www/html目录。