6.2 KiB
6.2 KiB
宿主机部署说明
HookPilot 直接部署在 Linux 宿主机上,由 systemd 管理,通过 HTTPS 反向代理对外提供服务。脚本以服务账户身份运行,可以操作该账户有权访问的文件和命令。
1. 环境要求
- Linux(systemd),x86_64 或 arm64
- Node.js 22.13 及以上(使用内置的
node:sqlite,无需编译原生模块) - Bash
- Nginx 或 Caddy(提供 HTTPS)
node -v # 应输出 v22.13.0 或更高
2. 构建
可以在服务器上直接构建,也可以在其他机器构建后复制整个目录。
git clone <仓库地址> /opt/hookpilot # 或将项目目录上传到 /opt/hookpilot
cd /opt/hookpilot
npm ci
npm run build # 构建前端(web/dist)与后端(server/dist)
npm prune --omit=dev # 可选:移除开发依赖
3. 创建服务账户与目录
默认使用专用账户 hookpilot,数据目录 /var/lib/hookpilot:
sudo useradd --system --home-dir /var/lib/hookpilot --create-home --shell /usr/sbin/nologin hookpilot
sudo chmod 700 /var/lib/hookpilot
sudo chown -R root:root /opt/hookpilot # 程序目录只读,服务账户无需写权限
数据目录结构(服务启动时自动创建):
| 路径 | 内容 |
|---|---|
hookpilot.db |
SQLite 数据库:管理员、会话、接口、脚本版本、任务与输出、系统设置 |
scripts/<接口ID>/v<版本>.sh |
各脚本版本的文件,执行时由数据库内容校验并重写 |
runs/<任务ID>/request.json |
任务执行期间的请求文件(HOOK_REQUEST_FILE),结束后删除 |
workspace/ |
未配置工作目录时的默认工作目录 |
脚本需要访问的其他目录,请用常规的文件权限授予 hookpilot 账户,例如:
sudo chown -R hookpilot:hookpilot /srv/my-app
4. 配置
sudo mkdir -p /etc/hookpilot
sudo cp deploy/hookpilot.env.example /etc/hookpilot/hookpilot.env
sudo chmod 600 /etc/hookpilot/hookpilot.env
sudo nano /etc/hookpilot/hookpilot.env
建议设置 HOOKPILOT_ADMIN_PASSWORD 作为初始密码(只在首次启动、数据库中还没有管理员时生效)。未设置时会随机生成,并打印在服务日志中。
5. 安装 systemd 服务
sudo cp deploy/hookpilot.service /etc/systemd/system/hookpilot.service
# 如果 node 不在 /usr/bin/node,请修改 ExecStart(可用 `which node` 查看)
sudo systemctl daemon-reload
sudo systemctl enable --now hookpilot
sudo systemctl status hookpilot
journalctl -u hookpilot -f # 查看日志,未设置初始密码时在这里找到随机密码
服务停止或重启时:
- 运行中的任务会被终止(整个进程组),状态记为“中断”,不会自动重跑;
- 排队中的任务保留在数据库中,服务启动后按原顺序继续执行;
- 服务异常退出(如被
kill -9、断电)后再启动,上次运行中的任务同样标记为“中断”。
6. 配置 HTTPS 反向代理
服务默认只监听 127.0.0.1:8787,由反向代理提供统一域名和 HTTPS。
- Nginx:参考
deploy/nginx.conf.example - Caddy:参考
deploy/Caddyfile.example(自动申请证书)
注意事项:
- 同步模式的接口会等脚本执行完才响应,代理的读取超时要大于最长脚本超时加排队时间。
- 代理的请求体上限应不小于
HOOKPILOT_BODY_LIMIT(默认 1 MiB)。 - 代理与服务不在同一台机器时,把
HOOKPILOT_TRUST_PROXY设置为代理的 IP,否则执行记录中的请求来源会显示为代理地址。 - 使用 HTTPS 访问时登录 Cookie 自动带
Secure标记(HOOKPILOT_COOKIE_SECURE=auto)。
7. 按命令授予提权
脚本默认只有 hookpilot 账户的权限。确实需要重启系统服务或修改受保护文件时,由部署者在 sudoers 中按具体命令授权,不要授予全部权限:
sudo visudo -f /etc/sudoers.d/hookpilot
# 只允许无密码执行这两条命令
hookpilot ALL=(root) NOPASSWD: /usr/bin/systemctl restart nginx
hookpilot ALL=(root) NOPASSWD: /usr/bin/systemctl reload caddy
脚本中使用 sudo -n(不交互询问密码,未授权时立即失败):
sudo -n /usr/bin/systemctl restart nginx
平台页面不提供切换系统用户的功能。启用提权后请保持 systemd 单元中 NoNewPrivileges 处于关闭状态。
8. 安全要点
- 管理端使用登录会话,Webhook 使用每个接口独立的 Token,两种凭证互不通用;Token 只保存哈希。
- 执行子进程使用显式构造的环境(
PATH、HOME、USER、LANG与HOOK_变量),不继承服务的环境变量与凭证。 - 请求数据只通过环境变量和请求文件传给脚本,不会替换进脚本文本或拼接成 Shell 命令。脚本中请始终用双引号引用变量(
"$HOOK_IP")。 - 平台面向可信管理员:任何能登录管理界面的人都能以服务账户身份执行任意命令,请使用强密码并限制管理界面的访问来源(如在代理层对
/做 IP 白名单、仅放行/hooks/)。 - 连续登录失败 10 次后,该来源 IP 锁定 15 分钟。
9. 升级、备份与维护
升级:
cd /opt/hookpilot
git pull # 或替换为新版本文件
npm ci && npm run build
sudo systemctl restart hookpilot
数据库结构变更会在启动时自动迁移。
备份: 停止服务后复制整个数据目录;或在运行中使用 SQLite 在线备份:
sudo -u hookpilot sqlite3 /var/lib/hookpilot/hookpilot.db ".backup '/var/backups/hookpilot.db'"
忘记管理员密码:
cd /opt/hookpilot
sudo -u hookpilot env HOOKPILOT_DATA_DIR=/var/lib/hookpilot node server/dist/cli.js reset-password
# 或指定新密码:
sudo -u hookpilot env HOOKPILOT_DATA_DIR=/var/lib/hookpilot HOOKPILOT_NEW_PASSWORD='新密码' node server/dist/cli.js reset-password
重置后所有登录会话失效。
日志清理: 超过“日志保留天数”(默认 30 天)的已结束执行记录及其输出每小时自动清理一次,可在“系统设置”中调整。