Nginx + Hexo 实现博客备份、自动部署及全站https

我的博客最初是部署在GitHub Pages上,由于万里长城的原因有时候打开极慢,而且使用自定义域名的时候无法启用https。我手上还有一台鹅厂的1C1G1M小水管云服务器,使用Nginx HTTP server,配合Let’s Encrypt的免费服务器证书、GitHub的webhooks服务,最终实现博客源文件的版本控制、服务端网站的自动更新部署。

简介

Hexo是一个基于Node.js的博客框架,每撰写一篇日志,Hexo会生成出静态的博客页面,不依赖任何动态文件,这使得我们可以使用GitHub Pages发布个人博客。这种情况下,每次对博客的修改都需要进行博客构建、发布的步骤,整个过程稍显麻烦。并且更换电脑撰写博客时需要重新搭建Hexo环境以及拷贝博客的Hexo源文件。如果需要使用个人域名解析到github.io的ip地址,也不能够开启https。

如果在GitHub仓库托管一份Hexo的源文件,在我更新博客后push到仓库里,云服务器自动从GitHub下载Hexo的源文件,然后进行构建步骤,通过Nginx对外提供访问。这样,在我们写完日志之后,就只需进行push操作,在其它的机器,也可以clone一份GitHub仓库的Hexo源文件,然后开始更新博客。

基本思路

  1. GitHub创建私有仓库yangyilts/hexo,用于托管Hexo源文件
  2. 开启GitHub的webhooks服务,当仓库yangyilts/hexo收到新的push时通知云服务器
  3. 云服务器收到webhooks通知的时候,pull新的Hexo源文件,在服务器中完成静态页面的构建
  4. 云服务器配置Nginx和SSL证书进行静态页面的发布,页面文件在hexo目录的public/目录下

我的Hexo源文件存放在一个私有仓库里,博客的源文件一般不涉及重要的隐私,但是如果托管于公开仓库,会暴露博客的配置文件,整个博客暴露在别人眼下也感觉有点不舒服。因为我还有一段时间的GitHub私有仓库优惠,所以暂时托管于GitHub。替代方案有国内的Coding,他家提供有限的私有仓库,托管一个博客已经足够了。

配置环境

本地机器环境

node.js、hexo、git以及配置git ssh密钥是基本环境,搜索一下有很多。

环境配置参考博文:零基础免费搭建个人博客-hexo+github

针对“国内拉npm比拉屎还难”的情况,是真的,可以切换到淘宝镜像,输入命令:

$ npm install -g cnpm --registry=https://registry.npm.taobao.org

之后就使用cnpm 代替npm

云服务器环境

Hexo

同样也需要node.js、hexo、git以及配置git ssh密钥的基本环境。

clone源文件仓库到服务器

$ mkdir /usr/share/hexo
$ cd /usr/share/hexo
$ git clone git@github.com:yangyiLTS/hexo.git

然后需要重新安装hexo的依赖插件,之后不需要hexo init,直接

$ hexo clean && hexo g

Nginx

我用的服务器镜像是Centos 7,首先安装Nginx

$ yum install -y nginx

修改/etc/nginx/nginx.conf文件中的server配置,举个例子

server {
    listen       80;
    server_name  your domain name;

    #charset koi8-r;

    #access_log  logs/host.access.log  main;

    location / {
        # your hexo/public dir
        root   /hexo/public;
        index  index.html index.htm;
    }

    ...
}

其实只要在默认文件内容下修改域名和网站根目录就可以了(网站根目录是hexo博客目录的public/目录),然后重启nginx

$ nginx -s reload

这个时候,如果域名解析、服务器访问控制都设置正确,hexo已经成功进行过$ hexo g操作的情况下,就可以通过域名访问到博客了。

为博客开启https

其实开启https的作用并不大,但是基于小绿锁的强迫症,不免得要折腾一番。好在申请Let’s Encrypt的免费证书也不是特别麻烦,有了小绿锁之后感觉整个博客都不一样了。

这一小节的参考博客

Let’s Encrypt 简介

Let’s Encrypt是一个免费并且开源的CA,且已经获得Mozilla、微软等主要浏览器厂商的根授信。它极大低降低DV证书的入门门槛,进而推进全网的HTTPS化。

Let’s Encrypt 安装

以官方推荐的 letsencrypt-auto 脚本进行安装:

$ git clone https://github.com/letsencrypt/letsencrypt

$ cd letsencrypt

$ ./letsencrypt-auto --help

申请SSL证书

由于nginx已在运行中,故使用webroot模式来获取证书,命令:

$ ./letsencrypt-auto certonly --webroot --webroot-path /usr/share/hexo/public -d www.yangyilts.com --agree-tos --email youremail@mail.com

证书申请成功后会显示证书的路径,以及到期时间。

配置Nginx

生成2048位 DH parameters:

$ openssl dhparam -out /etc/ssl/certs/dhparams.pem 2048

修改nginx.conf
server {

listen 80;

server_name www.yangyilts.com;

return 301 https://$server_name$request_uri;

}

server {
    listen       443 ssl;
    server_name  www.yangyilts.com;

    ssl_certificate /etc/letsencrypt/live/www.yangyilts.com/fullchain.pem;

    ssl_certificate_key /etc/letsencrypt/live/www.yangyilts.com/privkey.pem;

    ssl_dhparam /etc/ssl/certs/dhparams.pem;

    ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';

    ssl_prefer_server_ciphers  on;

    location / {
        root   /usr/share/hexo/public;
        index  index.html index.htm;
    }

    ...
}

其中配置了使http请求强制跳转至https的域名重定向。

然后访问https://www.yangyilts.com/测试

博客的自动构建与发布

http server布置好之后,需要搭建自动构建博客静态页面的服务,这里用到一个Go语言编写的Webhook工具,以及GitHub的Webhooks服务。区分一下两个Webhook:

Webhook工具是一个Go语言实现、运行在服务端的,用于处理来自GitHub的Webhooks消息的工具。它能在服务器上打开一个端口,监听来自GitHub的Webhooks消息,如果收到消息,就可以执行一个制定的脚本。

Webhooks是Github仓库(Coding也有)提供的一种服务。它的功能是当GitHub仓库发生某种事件(例如push)时,向指定的URL发送一个HTTP POST请求。

这一小节的参考博客。

Webhook工具配置

releases中下载编译完成的文件,然后解压得到一个可执行文件webhook

$ wget https://github.com/adnanh/webhook/releases/download/2.6.8/webhook-linux-amd64.tar.gz

新建一个 hooks.json,需要指定一个"id",以及"secert""execute-command"处填入收到通知后,需要执行的build.sh脚本的地址,"command-working-directory"填入执行脚本的目录,也就是hexo目录。下面是示例

// hooks.json
[
  {
    "id": "webhook_id",
    "execute-command": "/path/build.sh",
    "command-working-directory": "/path",
    "trigger-rule":
      {
        "match":
        {
          "type": "payload-hash-sha1",
          "secret": "yoursecret",
          "parameter": 
          {
            "source": "header",
            "name": "X-Hub-Signature"
          }
        }
      }
  }
]

其中"secert"的作用是使用hash验证收到的Post请求是否来源于合法的Git服务器。

新建一个脚本/usr/share/hexo/build.sh:

#!/bin/bash

rm -rf update.log
git pull | tee build.log
hexo clean && hexo g  | tee build.log

然后,使用命令
$ ./webhook -hooks hooks.json -verbose
就可以运行Webhook了

GitHub Webhooks配置

这里,我要使用的是当仓库收到push时,向我云服务器的域名发送一个post请求。

webhooks的设置在仓库的setting里面:

添加一个webhook

Secret填入上面设置的"secert",PayloadURL填入http://yourdomain.com:9000/hooks/webhook_id,然后post请求会被发到服务器的9000端口。

运行

在GitHub新建一个Webhook的时候,GitHub会自动发送一个ping事件的POST

如果POST请求被服务器上的Webhook成功响应,就会返回200 OK状态。如果返回值不是200,则需要检查配置的问题,然后Redeliver重新发送POST请求。

之前启动的Webhook会在退出服务器终端后终止,使用nohup使它长驻后台

$ nohup ./webhook -hooks /path/hooks.json -verbose > webhook.log 2>&1 &

收尾

最后,在本地Hexo目录下写一个Windows批处理public.bat

git add -A
git commit -m "updated %date:~0,10% %time%"
git push
hexo clean && hexo g && hexo d
pause

批处理的最后我还是用hexo d把博客发布到GitHub Pages,做一个备份。这个步骤当然也可以在远程服务器执行。

这样,当我们写完Mrakdown保存之后,只需要运行一次public.bat,就可以完成博客的所有发布工作了。

-------------本文结束 感谢阅读-------------

本文标题:Nginx + Hexo 实现博客备份、自动部署及全站https

文章作者:YANG Yi

发布时间:2018年01月21日 - 02:01

最后更新:2018年01月23日 - 20:01

原始链接:https://www.yangyilts.com/2018/Nginx-Hexo-实现博客自动部署及全站https.html/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。