部署hexo博客到腾讯云服务器

同步部署的方法方法很多,此处只成功实现了一种,其他方式总有权限问题。

写在前面

对不熟悉Linux操作的同学建议使用同步软件,更节约精力及时间。

本文为一边踩坑一边实现,结构较乱,还请自行验证。

部署方式

  • git 本地提交最新版至github及云服务器–回调时pull操作总提示权限问题
  • ftp 需开放其他端口–不安全
  • 同步软件 需双端启用同步软件,更消耗资源—Syncthing
  • gh 本地提交最新版至github,调用webhooks更新云服务的资源

最后使用gh成功完成同步更新。

环境配置

1
2
3
4
5
6
7
[root@VM-0-16-centos ~]# git --version
git version 1.8.3.1
[root@VM-0-16-centos ~]# nginx -v
nginx version: nginx/1.21.4
[root@VM-0-16-centos ~]$ gh version
gh version 2.14.7 (2022-08-25)
https://github.com/cli/cli/releases/tag/v2.14.7

创建git仓库并使用hooks实现自动部署

1
2
3
4
5
[root@VM-0-16-centos ~]# pwd
/root
[root@VM-0-16-centos ~]# sudo git init --bare blog.git
Initialized empty Git repository in /root/blog.git/
[root@VM-0-16-centos ~]# vim /root/blog.git/hooks/post-receive

hooks目录内没有post-receive,需要手动创建并保存,之后在post-receive增加下面两行,

1
2
#!/bin/sh
git --work-tree=/www/wwwroot/laiczhang.github.io --git-dir=/root/blog.git checkout -f

表明在/root/blog.git/www/wwwroot/laiczhang.github.io执行checkout -f命令,当我们把博客写好后更新,服务器端可以同步部署。

保存并赋予权限

1
[root@VM-0-16-centos ~]# chmod +x /root/blog.git/hooks/post-receive

本地设置

打开Hexo博客根目录下的_config.yml,将deploy下面修改为:

1
2
3
4
5
6
7
8
9
10
# Deployment
## Docs: https://hexo.io/docs/deployment.html
deploy:
- type: git
repo:
github: git@github.com:LaicZhang/laiczhang.github.io.git
branch: master
- type: git
repo: root@服务器公网ip:/root/blog.git
branch: master

本步骤由于我的ssh配置有问题,一直报错

1
2
3
4
5
Permission denied (publickey,gssapi-keyex,gssapi-with-mic).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

云服务器设置

点击generating a new ssh key,在本机上生成一个新的ssh key,并将其添加到项目的deploy key中。

deploy key页面位置:https://github.com/<yourname>/<yourrepo>/settings/keys

clone

1
2
3
cd /www/wwwroot/<yourrepo>
git clone git@github.com/<yourname>/<yourrepo>
// 国内clone速度极慢,可以将github.com替换为git.zhlh6.cn进行加速

nginx配置

1
sudo nginx -t  #查看nginx配置路径

我的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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
server
{
listen 80;
listen 443 ssl http2;
listen [::]:443 ssl http2;
listen [::]:80;
server_name coding.zyha.cn;
index index.php index.html index.htm default.php default.htm default.html;
root /www/wwwroot/laiczhang.github.io/;

#ERROR-PAGE-START 错误页配置,可以注释、删除或修改
#error_page 404 /404.html;
#error_page 502 /502.html;
#ERROR-PAGE-END

#PHP-INFO-START PHP引用配置,可以注释或修改
include enable-php-81.conf;
#PHP-INFO-END

#REWRITE-START URL重写规则引用,修改后将导致面板设置的伪静态规则失效
include /www/server/panel/vhost/rewrite/coding.zyha.cn.conf;
#REWRITE-END

#禁止访问的文件或目录
location ~ ^/(\.user.ini|\.htaccess|\.git|\.svn|\.project|LICENSE|README.md)
{
return 404;
}

#一键申请SSL证书验证目录相关设置
location ~ \.well-known{
allow all;
}

location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
{
expires 30d;
error_log /dev/null;
access_log /dev/null;
}

location ~ .*\.(js|css)?$
{
expires 12h;
error_log /dev/null;
access_log /dev/null;
}
access_log /www/wwwlogs/coding.zyha.cn.log;
error_log /www/wwwlogs/coding.zyha.cn.error.log;
}

coding.zyha.cn替换为博客域名,将root /www/wwwroot/laiczhang.github.io/;此处的路径更改为上方work tree对应的路径即可。

验证

由于之前部署在oss上,有DNS缓存,所以需要等待一段时间或手动修改hosts指定IP以预览效果,等待时间可以根据实际情况调整。

成功部署

自动更新

如果你的ssh能够正常push,那云服务器上的文件也将跟随github仓库一起更新,但是我有问题,所以使用了宝塔提供的webhooks来解决。

填入下方调用代码:

1
2
3
4
5
6
7
8
9
10
if test $1 = 'pull'
then
echo 'update:' $(date '+%Y-%m-%d %H:%M:%S')
cd /www/wwwroot/laiczhang.github.io
git reset --hard origin/master
git pull
chown -R www:www ./
chmod -R 755 ./
echo ""
fi
1
2
3
4
GET/POST:
http://<yourip>:<yourport>/hook?access_key=<yourkey>&param=pull
@param access_key string HOOK密钥
@param param string 自定义参数(在hook脚本中使用$1接收)

在更新完成后请求一次此回调接口,响应json{"code": 1}即调用成功。

成功触发接口后仍然未更新

打开终端手动pull一次,发现代码冲突,并未成功合并代码。

1
2
Please, commit your changes or stash them before you can merge.
Aborting

解决方案

1
2
3
4
5
6
git fetch
git reset --hard HEAD
git merge origin/$CURRENT_BRANCH

// 我使用的是 gh repo sync --branch master ,两者等价
// 此处我的仓库是使用的master分支,疫情之后`github`将默认分支更新为main,请注意分支名正确

带有 --hard 选项的 git reset 命令会将分支重置为我们刚刚获取的内容。它还将丢弃对跟踪文件的任何本地更改,并且将删除未跟踪的文件。

请谨慎使用,因为任何本地更改都将丢失。此次由于本博客最新版均提交之后github,所以不考虑手动解决冲突问题,直接覆盖旧代码即可。

更新后的回调代码

1
2
3
4
5
6
7
8
9
10
11
if test $1 = 'pull'
then
echo 'update:' $(date '+%Y-%m-%d %H:%M:%S')
cd /www/wwwroot/laiczhang.github.io
git stash # 存储更改,避免冲突
git stash drop stash@{0} # 删除stash中第一个队列
gh repo sync --branch master
chown -R www:www ./
chmod -R 755 ./
echo ""
fi