Repository navigation
Releases: zxc7563598/hook-exec
Release list
v1.0.0
接收 GitHub webhook,按仓库触发服务器上预先放好的 shell 脚本。
一个二进制、一个 SQLite 文件、一个脚本目录,没有外部依赖。
为什么有这个东西
手上有一堆博客、文档站和小服务,分散在不同仓库里。让每个服务自己监听自己的 webhook 并不是做不到,但每加一个站就要重复一遍「起个小 HTTP 服务 + 验签 + 解析 payload + 调部署命令」,而且这些逻辑散在各处,出没出问题得一个个去看。
HookExec 把这件事收敛成一个常驻服务:所有仓库的 webhook 都打到它这里,它按 owner/repo 找到对应的脚本执行。加一个新站就是「新建一个项目 + 传一个脚本」,不用再动服务本身。
特性
- 单二进制部署 —— SQLite 走纯 Go 实现,交叉编译不需要目标平台工具链;前端资源全部内嵌,不依赖任何外网 CDN
- 管理页 —— 项目增删改、脚本只读预览、执行记录与输出、按项目和状态筛选、配置导入导出
- 同项目串行,跨项目并行 —— 两次
push连着到来时部署脚本按顺序跑,不会在服务器上互相打架;不同项目并行,总量由全局并发数兜住 - 幂等 —— GitHub 手动 redeliver 重复投递同一个 delivery 时不会重复执行
- 超时终止整个进程组 —— 脚本派生的
npm run build、后台起的服务都会被一起收掉,不留孤儿进程 - 执行记录自动清理 —— 按保留天数和每项目条数两条约束取更严格者
- 优雅停机 —— 先停止收新请求,等在途脚本跑完;
kill -9后重启会把残留记录收尾成「已中断」,不会留下看起来永远在跑的记录
安全模型
网页端不能编写或修改脚本。 可执行内容全部来自 <数据目录>/shell/,由你自己通过 scp / ansible / git 传上去。由此带来的结果是:拿到管理页的账号密码,只意味着能从服务器上已有的脚本里挑一个执行,而不是能执行任意命令。
脚本路径的解析收敛在一处:拼出来的路径必须落在脚本目录内(软链解掉之后再判一次)、必须是普通文件,而且每次执行前都重新校验,不信任数据库里存的值 —— 即使有人直接改库、或导入一份恶意配置,也逃不出脚本目录。
管理页的凭证仍然是服务器级机密(持有者可以任选脚本执行,也能读到它们的源码),请通过 HTTPS 反代暴露,不要直接裸奔在公网上。
下载
| 平台 | 文件 |
|---|---|
| Linux x86_64 | hook-exec_v1.0.0_linux_amd64.tar.gz |
| Linux arm64 | hook-exec_v1.0.0_linux_arm64.tar.gz |
| macOS Intel | hook-exec_v1.0.0_darwin_amd64.tar.gz |
| macOS Apple Silicon | hook-exec_v1.0.0_darwin_arm64.tar.gz |
checksums.txt 里有全部产物的 SHA-256。每个包内是一个 hook-exec 可执行文件和 README,解压即用。
快速开始
tar -xzf hook-exec_v1.0.0_linux_amd64.tar.gz
cd hook-exec_v1.0.0_linux_amd64
./hook-exec --listen 127.0.0.1:9000 --data-dir /opt/hookexec首次启动会自动建好数据目录和 shell/ 子目录。没给密码时会随机生成一个并打印出来,只显示这一次:
level=WARN msg=未指定密码,已生成随机密码。请立即保存,此密码只显示这一次 user=admin password=...
跑起来之后:
- 打开
http://127.0.0.1:9000/web登录管理页 - 把脚本放进
<数据目录>/shell/并chmod +x,点「重新扫描」 - 新建项目,把仓库和脚本关联起来
- 到 GitHub 仓库的 Settings → Webhooks 填上
https://你的域名/,Content type 选application/json,Secret 填和项目里一致的那个
完整文档见仓库 README。
系统要求
- Linux 或 macOS,64 位
- 暂不支持 Windows:进程组管理(
Setpgid、kill(-pgid))是 Unix 专有的,而「超时终止整个进程组」是这里明确的行为保证;可执行位在 Windows 上也没有意义
macOS 从浏览器下载的包会被打上隔离属性,首次运行可能被 Gatekeeper 拦下:
xattr -d com.apple.quarantine hook-execcurl 下载的不会带这个属性。