Webhook 自动部署代码完整教程

Webhook 是实现代码自动部署的轻量级方案。当你向 Git 仓库推送代码时,代码托管平台会向你配置的 URL 发送 HTTP 请求,搬瓦工 VPS 上的 Webhook 服务器接收到请求后自动执行部署脚本。本文将介绍如何实现这一流程。购买搬瓦工使用优惠码 NODESEEK2026 享 6.77% 折扣。

一、工作原理

自动部署流程:开发者推送代码到 GitHub/Gitea → 平台发送 Webhook HTTP POST → VPS 上的 Webhook 服务器接收请求 → 验证签名 → 执行部署脚本(git pull、构建、重启服务)。

二、方案一:使用 webhook 工具

webhook 是一个用 Go 编写的轻量级 Webhook 服务器,非常适合在搬瓦工 VPS 上运行。

# 安装 webhook
apt update && apt install webhook -y

# 或下载二进制
wget https://github.com/adnanh/webhook/releases/download/2.8.1/webhook-linux-amd64.tar.gz
tar -xzf webhook-linux-amd64.tar.gz
mv webhook-linux-amd64/webhook /usr/local/bin/

配置 Webhook

# 创建配置文件 /etc/webhook/hooks.json
mkdir -p /etc/webhook
cat > /etc/webhook/hooks.json << 'EOF'
[
  {
    "id": "deploy-website",
    "execute-command": "/opt/scripts/deploy.sh",
    "command-working-directory": "/opt/my-website",
    "response-message": "Deployment started",
    "trigger-rule": {
      "and": [
        {
          "match": {
            "type": "payload-hmac-sha256",
            "secret": "your-webhook-secret",
            "parameter": {
              "source": "header",
              "name": "X-Hub-Signature-256"
            }
          }
        },
        {
          "match": {
            "type": "value",
            "value": "refs/heads/main",
            "parameter": {
              "source": "payload",
              "name": "ref"
            }
          }
        }
      ]
    }
  }
]
EOF

编写部署脚本

# /opt/scripts/deploy.sh
cat > /opt/scripts/deploy.sh << 'EOF'
#!/bin/bash
set -e

LOG_FILE="/var/log/deploy.log"
DEPLOY_DIR="/opt/my-website"

echo "$(date) - Starting deployment..." >> $LOG_FILE

cd $DEPLOY_DIR

# 拉取最新代码
git pull origin main >> $LOG_FILE 2>&1

# Node.js 项目
npm install --production >> $LOG_FILE 2>&1
npm run build >> $LOG_FILE 2>&1
pm2 restart my-app >> $LOG_FILE 2>&1

# 或 Python 项目
# source .venv/bin/activate
# pip install -r requirements.txt
# systemctl restart my-app

echo "$(date) - Deployment completed!" >> $LOG_FILE
EOF

chmod +x /opt/scripts/deploy.sh

启动 Webhook 服务

# 测试运行
webhook -hooks /etc/webhook/hooks.json -verbose -port 9000

# Systemd 服务
cat > /etc/systemd/system/webhook.service << 'EOF'
[Unit]
Description=Webhook Server
After=network.target

[Service]
ExecStart=/usr/local/bin/webhook -hooks /etc/webhook/hooks.json -port 9000
Restart=always

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable webhook && systemctl start webhook

三、方案二:简易 Python Webhook

# /opt/scripts/webhook-server.py
from http.server import HTTPServer, BaseHTTPRequestHandler
import hmac, hashlib, subprocess, json

SECRET = b'your-webhook-secret'

class WebhookHandler(BaseHTTPRequestHandler):
    def do_POST(self):
        content_length = int(self.headers['Content-Length'])
        payload = self.rfile.read(content_length)

        # 验证签名
        signature = self.headers.get('X-Hub-Signature-256', '')
        expected = 'sha256=' + hmac.new(SECRET, payload, hashlib.sha256).hexdigest()

        if not hmac.compare_digest(signature, expected):
            self.send_response(403)
            self.end_headers()
            return

        # 检查是否是 main 分支
        data = json.loads(payload)
        if data.get('ref') == 'refs/heads/main':
            subprocess.Popen(['/opt/scripts/deploy.sh'])

        self.send_response(200)
        self.end_headers()
        self.wfile.write(b'OK')

HTTPServer(('0.0.0.0', 9000), WebhookHandler).serve_forever()

四、在 GitHub/Gitea 配置 Webhook

在代码仓库的 Settings → Webhooks 中添加:

  • Payload URLhttp://你的VPS-IP:9000/hooks/deploy-website
  • Content type:application/json
  • Secret:your-webhook-secret(与服务端一致)
  • Events:Just the push event

建议使用 Nginx 反向代理并配置 HTTPS,避免 Secret 在网络上明文传输。

五、Nginx 反向代理配置

server {
    listen 443 ssl;
    server_name webhook.example.com;

    ssl_certificate /etc/letsencrypt/live/webhook.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/webhook.example.com/privkey.pem;

    location /hooks/ {
        proxy_pass http://127.0.0.1:9000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

六、安全最佳实践

  • 始终验证 Webhook 签名,防止伪造请求。
  • 使用 HTTPS 传输,保护 Secret 不被截获。
  • 部署脚本使用低权限用户运行,避免 root。
  • 限制 Webhook 端口仅接受来自 GitHub/Gitea IP 的请求。
  • 记录部署日志,方便排查问题。

总结

Webhook 自动部署是比完整 CI/CD 系统更轻量的方案,适合个人项目和小团队。对于更复杂的部署需求,可以参考 Jenkins vs GitLab CI 对比。自建 Git 服务请参考 Git 服务器教程Gitea 部署教程。选购搬瓦工请访问 全部方案,使用优惠码 NODESEEK2026 享 6.77% 折扣,通过 bwh81.net 进入官网。

关于本站

搬瓦工VPS中文网(bwgvps.com)是非官方中文信息站,整理搬瓦工的方案、优惠和教程。我们不销售主机,不提供技术服务。

新手必读
搬瓦工优惠码

NODESEEK2026(优惠 6.77%)

购买时填入即可抵扣。