博客的自动部署

分类:笔记, 发布于:2019-02-01 21:00:00, 更新于:2019-03-28 23:21:23 CC-BY-NC-SAv4 评论

起因

本来博客的更新方法是利用cronjob每隔1或5分钟执行一次脚本,脚本每次都会从GitHub上拉取最新的版本并且执行更新页面的预处理指令。

然而这个预处理每次都要删库重新制作页面,后劲太大。所以后来更新了一下,脚本只有检测到远程库有新版本的时候才会更新,发现效果还是不咋地。特别是每次push之后要等1分钟才能看到新的内容。

所以就打算找一个更好的方法,每次在push指令后立即执行更新指令,其他情况下都不执行。

Git钩子

Git Hooks其实就是在git运行到某一阶段的时候去执行对应的(本地)指令,而Webhooks是会对某一个指定的URL发送请求。由于GitHub的服务器并不能自己访问,所以GitHub等托管服务只有Webhooks而没有Hooks。

如果想继续用GitHub之类的服务托管仓库,可以在服务器自己写一个PHP之类的页面,执行对应的代码。然而这样实在是太屑了,所以就还是改成用self-hosted git来存储代码。

实现方式

Git Hooks的对应脚本存放在/path_to_repo/hooks中,通常用到的是post-receive,在服务器收到push后执行。将post-receive.sample复制一份并改名,添加WX权限来确保git用户可以执行。

执行时如果需要切换目录必须要先删除环境变量GIT_DIRunset GIT_DIR),不然会导致执行出错。

删除了环境变量后直接cd到对应目录,然后进行对应的操作。需要注意的是,这个脚本中的所有命令都是以git用户来执行的,切换到其他用户的目录后可能会出现权限不足或者无法访问的情况。

sudoers

解决以上问题的方法是修改/etc/sudoers来给予git用户切换执行者的权限,先给sudoers文件添加W属性,然后加入以下内容

git ALL = (www-data) NOPASSWD: /usr/bin/git, /usr/bin/php

NOPASSWD表示这个切换不需要询问密码,没有这个会因为git SSH无法请求输入密码而出错。后面的指令用逗号分隔,所执行的文件名/指令要使用绝对路径。如果不知道绝对路径是哪个可以用whereis XXX查询。

然后将脚本中出现权限不足的指令修改为

sudo -u www-data git XXX
sudo -u www-data php XXX

就可以切换用户,享受对应的权限了。

这样的话在git push执行之后就可以看到Hooks文件执行的输出,成功把代码更新和部署放到了一起。

评论