从零开始搭建一个带有自动部署的 hexo 静态托管服务

这个网站,最开始使用的 Coding.net 提供的 page 服务。然而他们家的服务极其的不靠谱,我用的还是收费版的 page 服务,https 打开页面建立安全链接要等好久,运气不好的话还经常超时。并且他们家集成的 Let’s Encrypt 证书自动续签服务也不靠谱。遇到过几次自动续签失败,但是手动上去点一下就好了的情况。当初用 coding page 是为了省事,没想到服务会如此不稳定,于是还不如在境内搞一台 vps 从头自己搞。

背景 一些废话

其实一开始,我是想用 Hostker 的来着。他们家旧版的应用运行环境,资瓷 Git 版本控制,CDN 动静分离,域名不用备案就能享受到和境内服务器差不多的速度。然而在用 git 自动部署的时候遇到一点问题,Hostker 在生成应用之后,会自动创建一个 index.html 文件,使用 hexo 的自动部署插件尝试自动部署的时候,也会生成一个 index.html,并且会把本地的更改 force push 到远端的仓库。但是我猜测,从 git 仓库到 hostker 正真的运行环境应该还要再经历一次 pull,这个 pull 操作可能是没有加上 –force 之类的标识,导致 hexo 的更改和原先的内容有冲突,所以 index.html 里会有奇怪的东西(git 的冲突标识)。最后只好作罢。

p.s 刚才突然想到 Hoster 也提供了 FTP 服务,并且 hexo 也有 ftpSync 部署插件。其实可以通过 ftp 的方式来将代码部署到 hostker。 然而我已经…… emmmm有兴趣的朋友可以之后试试。

事前准备

本文的主要目的是备忘,并非小白教程,所以假定读者已经有一定的 Linux 基础知识和文档阅读能力
服务器我这次用的是阿里云轻量应用服务器,之所以没选传统的 ECS,原因有二:静态页面对计算能力的要求不高,轻量应用服务器足矣;ECS 的费用不太经济。归根结底一个字:“穷”。

服务器到手后,要做的准备工作如下:

  • 安装 Ubuntu 16.04 系统
  • 生成一对 ssh 密钥,并将公钥在服务器上配置妥当。由于之后的 git 和 ssh 都会需要认证,所以推荐采用密钥的方式来登陆而非密码。小白参考这里
  • 安全加固:禁止 SSH 密码登陆,更改 SSH 端口等。
  • 升级软件,安装必要工具: apt-get updateapt-get upgradeapt-get install git
  • 正确配置所需域名的 dns 与解析

建立 http 服务

Nginx 安装 & 配置

Ubuntu 自带的 Nginx 版本够用,使用 Ubuntu 官方的 apt 源安装,轻松加愉快。

1
apt-get install nginx

修改 Nginx 配置文件,文件位于 /etc/nginx/ 目录。官方推荐的做法是在 sites-available 中建立每一个站点的配置文件,再通过软连接的方式连接到 sites-enabled,遵循之:

建立站点配置文件 /etc/nginx/sites-available/blog.cdog.me。假定源码位于 /path/to/app

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
server {
listen 80 ;
listen [::]:80 ;

listen 443 ssl http2;
listen [::]:443 ssl http2;

server_name blog.cdog.me;

root /path/to/app;

location / {
try_files $uri $uri/ =404;
}

location ^~ /.git {
deny all;
}
}

建立软连接:

1
ln -s /etc/nginx/sites-available/blog.cdog.me /etc/nginx/sites-enabled

测试配置是否有误:

1
nginx -t

重新载入 nginx 使配置生效:

1
nginx -s reload

申请 Let’s Encrypt 证书

使用 Let’s Encrypt 官方推荐使用的 certbot 工具。参考 这篇教程

自动配置完成之后,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
33
34
35
36
server {

listen 443 ssl http2;
listen [::]:443 ssl http2;

server_name blog.cdog.me;

root /path/to/app;


location / {
try_files $uri $uri/ =404;
}

location ^~ /.git {
deny all;
}


ssl_certificate /etc/letsencrypt/live/blog.cdog.me/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/blog.cdog.me/privkey.pem; # managed by Certbot
}
server {
if ($host = blog.cdog.me) {
return 301 https://$host$request_uri;
} # managed by Certbot


listen 80 ;
listen [::]:80 ;

server_name blog.cdog.me;
return 404; # managed by Certbot


}

此时此刻,在 /path/to/app 下建立一个 index.html,访问对应的地址应该能正常看到网页啦。

源码 git 托管

hexo 提供了非常方便的 git 部署功能。需要在主机上建立一个 git 仓库:

1
2
3
mkdir /path/to/git
cd /path/to/git
git init --bare

将这个仓库添加到 hexo 的部署目标中,在 hexo 项目根目录下的 _config.yml 的底部添加:

1
2
3
4
deploy:
- type: git
repo: ssh://root@your.domain:port/path/to/git
branch: master

执行 hexo 部署:

1
hexo g -d

如果不出意外,这个时候就已经把代码 push 到主机上了。

自动部署

现在,在我们的主机上已经有了一个能工作的 http 服务器和 hexo 项目的代码,接下来需要做的是把这两者建立联系,并且实现 git 推送后 http 服务的内容自动更新。

通过 git 的 post-receive 钩子可以实现我们想要的功能。在 /path/to/git/hooks 下建立 post-receive,内容如下:

1
2
#!/bin/sh
git --work-tree=/path/to/app --git-dir=/path/to/git checkout -f

加上可执行权限:

1
chmod +x post-receive

删除之前建立的 index.html

1
rm /path/to/app/index.html

至此,git 钩子就添加完毕了。在本地重新运行 hexo g -d 命令,在访问对应的地址,就能看到网站已经正常部署了。

事后

整个部署过程不算复杂,总共花了一个下午不到就搞定了。过程写得比较简略,遇到问题欢迎在评论区讨论~