feat: 添加 Gitea webhook 自动部署功能

- 新增独立的 webhook 服务 (Go, 端口 9000)
- HMAC-SHA256 签名验证
- 零停机热更新部署
- 自动清理旧镜像
- 完整配置文档 WEBHOOK_SETUP.md
- 精简 README 版本历史为表格形式
This commit is contained in:
CHE LIANG ZHAO
2026-01-13 14:37:01 +08:00
parent 471bdeaf6b
commit 05ab270677
9 changed files with 1062 additions and 22 deletions

132
webhook/README.md Normal file
View File

@@ -0,0 +1,132 @@
# Webhook 服务
用于监听 Gitea webhook 事件,自动触发服务器拉取最新代码并重新构建部署。
## 特性
- ✅ 接收 Gitea webhook 推送事件
- ✅ HMAC-SHA256 签名验证
- ✅ 仅处理主分支 (master/main) 的推送
- ✅ 自动执行部署脚本
- ✅ 异步部署,快速响应
- ✅ 零停机热更新
## 配置
### 环境变量
| 变量 | 说明 | 默认值 |
|-----|------|-------|
| `WEBHOOK_PORT` | webhook 服务监听端口 | 9000 |
| `WEBHOOK_SECRET` | Gitea webhook 签名密钥 | your-webhook-secret |
| `REPO_PATH` | 仓库根目录路径 | /app |
### 部署脚本
脚本位置: `/app/deploy.sh`
执行以下操作:
1. 拉取最新代码 (`git pull`)
2. 热更新部署(零停机)
3. 自动清理旧镜像
4. 健康检查
## 安全性
### 设置 Webhook Secret
在 Gitea 中配置 webhook 时,需要设置 Secret
1. 生成一个随机密钥:
```bash
openssl rand -hex 32
# 输出示例: a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6
```
2. 在 Docker 容器中设置环境变量:
```yaml
environment:
WEBHOOK_SECRET: "a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6"
```
## Gitea Webhook 配置
### 1. 进入仓库设置
在 Gitea 中打开仓库,进入 **设置 → Webhook**
### 2. 添加新 Webhook
- **URL**: `http://<your-server>:9000/webhook`
- **内容类型**: `application/json`
- **密钥**: 使用上面生成的 Secret
- **触发器**: 勾选 `推送事件`
- **活跃**: 是
### 3. 测试连接
点击 "测试" 按钮验证连接
## 日志
查看部署日志:
```bash
# 查看容器日志
docker logs billai-webhook
# 查看部署脚本日志
docker exec billai-webhook tail -f /tmp/billai_deploy.log
```
## 访问端点
- **Webhook**: `POST /webhook`
- **健康检查**: `GET /health`
## 工作流
```
Gitea Push Event
Webhook Service (port 9000)
验证 HMAC-SHA256 签名
检查分支 (仅主分支)
异步触发部署脚本
执行 git pull
执行 docker-compose build/up
健康检查
部署完成
```
## 故障排除
### 签名验证失败
- 检查 Gitea 中配置的 Secret 是否与环境变量 `WEBHOOK_SECRET` 一致
### 部署脚本无法执行
- 确保 `deploy.sh` 存在于仓库根目录
- 检查文件权限:`chmod +x deploy.sh`
- 检查容器内是否有 git、docker 等工具
### Docker 操作失败
- 确保容器有权限访问 Docker Socket
- 在 docker-compose 中正确挂载 Docker Socket
```yaml
volumes:
- /var/run/docker.sock:/var/run/docker.sock
```
## 示例 docker-compose 配置
参考项目根目录的 `docker-compose.yaml`