服务器自动拉取仓库

问题引入

网站的静态html文件托管在了github仓库上,每次修改网页构建的文件就git push至github仓库,服务器再git pull拉取仓库,实现网站的更新。

按照这个流程,每修改一次网站,都要在服务器上执行一次git pull,很不方便。因此要让服务器自动执行这个过程,实现自动化。

假设网站静态文件仓库在/web/site/index,我们把自动化的脚本放在上一级/web/site1

方法一 Crontab定时更新

crontab是linux里自带的自动化程序,在crontab -e修改配置文件,定时执行shell命令(通常是运行一个shell脚本),达到自动化的目的。

创建更新仓库的sh脚本

nano /web/site1/auto-fetch.sh

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
#!/bin/bash
REPO_DIR="/web/site1/index" # 切换到git目录
cd "$REPO_DIR" || exit 1

echo "[`date`] Forcing git fetch and reset..." >> /web/site1/git_pull.log # 写入日志

# 取最新远程变更
git fetch origin

# 强制把本地重置为远程分支
git reset --hard origin/main

# 可选:清理多余文件
git clean -fd

echo "[`date`] Update complete" >> /web/site1/git_pull.log

别忘了赋权

1
chmod +x /web/site1/auto-fetch.sh

配置crontab

使用crontab -e修改crontab的配置文件

在末尾加入两行

1
2
*/1 * * * * /bin/bash /web/site1/auto-fetch.sh >> /web/site1/cron-sync.log 2>&1
0 0 * * * > /web/site1/cron-sync.log

第一行 */1 * * * *是每隔一分钟执行一次,运行auto-fetch.sh,并将错误输出连同标准输出写入cron-sync.log

第二行是每天0点清空cron-sync.log,避免日志文件无限增大。

保存退出后,crontab就立即生效了。

方法二 webhook实时更新

crontab的配置过程简单,但缺点是定时。因为是强制更新,因此crontab设置自动更新的时间间隔不宜过短,因为会影响性能。

webhook可以实时监听远程仓库的状态,当且仅当远程仓库变化时,服务器才自动push。

创建更新脚本

这一步参考crontab的auto-fetch脚本

编写webhook服务脚本

这里要用到python的flask模块

pip3 install flask

nano /web/site1/webhook_server.py

写入

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
from flask import Flask, request
import subprocess

app = Flask(__name__)

@app.route('/git-webhook', methods=['POST'])
def webhook():
    subprocess.Popen(['/web/site1/auto-fetch.sh'])
    return 'Webhook received', 200

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=9000)

根据自身情况修改 subprocess.Popen的脚本路径 和 port=9000 的端口号。(这个webhook是运行在服务器上的,注意端口是否被占用)

创建 systemd 服务管理 webhook

nano /etc/systemd/system/git-webhook.service

写入

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
[Unit]
Description=Git Webhook Listener
After=network.target

[Service]
User=root
WorkingDirectory=/web/site1
ExecStart=/usr/bin/python3 /web/site1/webhook_server.py
Restart=always

[Install]
WantedBy=multi-user.target

上面的User=root,按需修改成可以执行脚本的用户

启用并启动

1
2
3
systemctl daemon-reexec
systemctl daemon-reload
systemctl enable --now git-webhook.service

查看状态

sudo systemctl status git-webhook.service

github设置webhook

点进项目仓库,上边栏找到Settings,点击Webhooks。

点击Add webhook。

Payload URL = http://your-server-ip:9000/git-webhook

Content type = application/json

Events = Push events

保存后检查是否正常工作

定时清空日志

仍使用crontab来清空git的日志

只需要在crontab配置文件加一条即可:

0 0 * * * > /web/site1//web/site1/git_pull.log

小结

如果应付简单的场景,crontab足矣。

追求实时更新和性能,更推荐监听webhook的方式。

Licensed under CC BY-NC-SA 4.0
使用 Hugo 构建
主题 StackJimmy 设计