使用指南

June 25, 2026 · View on GitHub

English

本指南介绍 HookRun 的日常使用:CLI 命令、路由行为、响应格式和常见场景。


1. CLI 命令

所有命令支持全局 -c 参数指定配置文件路径:

hookrun -c /path/to/config.yaml <command>

默认配置路径:当前目录下的 config.yaml


init — 初始化配置

# 使用通用模板初始化(默认)
hookrun init

# 使用 GitHub webhook 模板初始化
hookrun init --template github

# 使用 GitLab webhook 模板初始化
hookrun init --template gitlab

# 覆盖现有文件无需确认
hookrun init --force

在当前目录创建 config.yamlhooks/example.yaml

可用模板:

模板说明
generic通用 webhook 模板,使用 Token 认证
githubGitHub webhook 自动部署,使用 HMAC 认证
gitlabGitLab webhook 自动部署,使用 Token 认证

relay — 查看 Relay 状态

# 查看当前实例的 relay 状态
hookrun relay status

# 列出已注册的下游目标(需 Bearer Token 认证)
hookrun relay targets

# 指定注册中心 Token(默认使用配置中的 relay_registry_token)
hookrun relay targets --token your-registry-token

HookRun 实例可以是以下四种 relay 角色之一:

角色说明
upstream接受下游注册(需配置 relay_registry_token
downstream向上游注册(需配置 relay_client
upstream+downstream同时作为上游和下游
none无 relay 配置

状态输出示例:

Relay Status
============
Role: upstream + downstream

Upstream (Registry):
  Enabled:     yes
  Targets:     3 registered
  Max entries: 100
  Max TTL:     300s

Downstream (Client):
  Enabled:        yes
  Upstream:       http://main:9000
  Registered as:  http://10.0.0.2:9000/webhook
  Tags:           prod, web
  TTL:            120s
  Connected:      yes
  Last heartbeat: 2026-06-24 14:00:00 (15s ago)
  Failures:       0

目标列表输出示例:

Registered Targets (3)
+------------------------------+------------+------+---------------------+
| URL                          | Tags       | TTL  | Last Seen           |
+------------------------------+------------+------+---------------------+
| http://10.0.0.2:9000/webhook | prod, web  | 120s | 2026-06-24 14:00:00 |
| http://10.0.0.3:9000/webhook | prod, api  | 120s | 2026-06-24 13:59:50 |
| http://10.0.0.4:9000/webhook | staging    | 60s  | 2026-06-24 14:00:05 |
+------------------------------+------------+------+---------------------+

start — 启动服务

# 守护模式(默认,后台运行)
hookrun start

# 前台模式(调试/终端使用)
hookrun start -f

# 指定配置文件路径
hookrun start -c /etc/hookrun/config.yaml
  • 守护模式会在 ~/.hookrun/ 创建 PID 文件
  • 前台模式直接将日志输出到终端

stop — 停止服务

hookrun stop
  • Linux/macOS:向进程发送 SIGTERM 信号
  • Windows:使用信号文件 IPC 机制(每 2 秒轮询一次)

restart — 重启服务

hookrun restart

等同于 stop + start。等待进程停止最多 15 秒后重新启动。


status — 查看状态

hookrun status

输出示例:

Status:  running
PID:     12345
Port:    9000
Rules:   3 config(s)
Uptime:  2h30m15s
Started: 2026-06-11 10:00:00

服务停止时:

Status: stopped (no PID file)

reload — 热重载配置

hookrun reload
  • 重新加载所有 YAML 文件(全局 + 规则配置),无需重启
  • Linux/macOS:使用 HTTP 重载 API (POST /_reload)
  • Windows:使用信号文件 IPC

重载后,新规则对后续请求立即生效。


validate — 校验配置

hookrun validate

输出示例:

Validating config: config.yaml
PASS: All configurations are valid
  Server port: 9000
  Webhook route: /webhook
  Allow all: false
  Max body size: 10 MB
  Log mode: daily
  Log path: ./logs
  Log retention: 30 days
  Config dir: ./hooks
  Rule files loaded: 1
  Relay registry: disabled
    - github-auto-deploy (2 rules: push-to-main, tag-release) [auth: token]

建议在启动或重载前运行 validate 以提前发现配置错误。


version — 查看版本

hookrun version

输出:

HookRun vx.y.z
Build time: 2026-06-11
Go version: go1.23.3
OS/Arch:    linux/amd64

help — 查看帮助

# 显示所有可用命令
hookrun help

# 显示指定命令的帮助
hookrun help relay
hookrun help relay status

# 也可使用 --help 或 -h 参数
hookrun start --help
hookrun relay -h

所有命令均支持 --help / -h 参数,用于显示详细用法和示例。


2. Webhook 路由

HookRun 支持两种 URL 模式:

定向路由:/webhook/{filename}

直接路由到指定 YAML 配置文件(按文件名不含扩展名匹配)。

POST /webhook/my-app
→ 匹配: hooks/my-app.yaml
→ 执行: 该文件中第一个匹配的规则
  • 配置文件不存在 → 404
  • 没有规则匹配 → 200 "No matching rules"

基础路由:/webhook

行为受 allow_all 控制:

allow_all行为
true遍历所有配置,匹配第一个规则后停止
false(默认)返回 400 错误(必须使用定向路由)

路由匹配示例

# 定向:直接到 hooks/frontend.yaml
POST /webhook/frontend

# 基础路由:遍历所有 YAML 文件
POST /webhook

健康检查

GET /health

返回:

{"status": "ok", "uptime": "2h30m15s", "rules": 3, "version": "x.y.z"}

当配置了 Relay 时,响应会包含额外的 relay 字段:

{"status": "ok", "uptime": "2h30m15s", "rules": 3, "version": "x.y.z", "relay": {"role": "upstream+downstream", "upstream_targets": 3, "downstream_connected": true}}

Relay API

GET /api/relay/status — 综合 Relay 状态(始终可用,无需认证)

返回当前实例的 relay 角色和状态,无论是否配置了 relay。

curl http://hookrun:9000/api/relay/status

响应(上游 + 下游):

{
  "role": "upstream+downstream",
  "upstream": {
    "enabled": true,
    "targets_count": 3,
    "max_entries": 100,
    "max_ttl": 300
  },
  "downstream": {
    "enabled": true,
    "upstream_url": "http://main:9000",
    "registered_url": "http://10.0.0.2:9000/webhook",
    "tags": ["prod", "web"],
    "ttl": 120,
    "connected": true,
    "last_heartbeat": "2026-06-24T14:00:00Z",
    "fail_count": 0
  }
}

响应(无 Relay):

{
  "role": "none",
  "upstream": {"enabled": false},
  "downstream": {"enabled": false}
}

注册池 API(需配置 relay_registry_token

仅在 server.relay_registry_token 已配置时可用(详见配置参考)。

POST   /api/relay/register   # 注册或刷新目标
DELETE /api/relay/register   # 注销目标
GET    /api/relay/targets    # 列出所有已注册目标

所有 Registry API 请求需携带 Bearer Token:

curl -H "Authorization: Bearer your-registry-secret" \
     http://main-hookrun:9000/api/relay/targets

3. 响应格式

所有 Webhook 响应均为 JSON 格式,消息使用英文。

成功(200)

{
  "code": 200,
  "message": "ok",
  "config": "github-auto-deploy",
  "rule": "push-to-main",
  "actions": 3
}

无匹配规则(200)

{
  "code": 200,
  "message": "No matching rules",
  "config": "github-auto-deploy"
}

认证失败(401)

{
  "code": 401,
  "message": "Authentication failed"
}

配置未找到(404)

{
  "code": 404,
  "message": "Config 'not-exist' not found"
}

执行被阻止(409)

policy: "block" 且任务仍在运行时:

{
  "code": 409,
  "message": "Task 'github-auto-deploy/push-to-main' is running, please try again later"
}

冷却中(429)

policy: "cooldown" 且处于冷却窗口内时:

{
  "code": 429,
  "message": "Task 'github-auto-deploy/push-to-main' is in cooldown, retry in 120 seconds"
}

基础路由已禁用(400)

allow_all: false 时请求 /webhook

{
  "code": 400,
  "message": "Base route iteration is disabled, please specify target: /webhook/{name}"
}

Relay Registry — 注册(200)

{
  "status": "registered",
  "targets_count": 3
}

Relay Registry — 注销(200)

{
  "status": "unregistered",
  "targets_count": 2
}

Relay Registry — 列出目标(200)

{
  "targets": [
    {
      "url": "http://10.0.0.5:9000/webhook/deploy-app",
      "tags": ["web", "prod"],
      "ttl": 120,
      "last_seen": "2026-06-11T10:00:00Z",
      "expires_at": "2026-06-11T10:02:00Z"
    }
  ],
  "total": 1
}

Relay Registry — 错误

状态码含义
401Bearer Token 缺失或无效
405方法不允许
429注册池已满(达到 max_registry_entries 上限)
503Relay Registry 未启用(未配置 relay_registry_token

4. 常见场景

场景 1:GitHub Push 自动部署

name: "github-deploy"
auth:
  hmac:
    header: "X-Hub-Signature-256"
    secret: "your-github-webhook-secret"
execution:
  policy: "block"
rules:
  - name: "deploy-main"
    filters:
      - type: "header"
        key: "X-GitHub-Event"
        operator: "eq"
        value: "push"
      - type: "body"
        key: "ref"
        operator: "eq"
        value: "refs/heads/main"
    actions:
      - type: "command"
        cmd: "cd /var/www/app && git pull origin {{.body.ref}} && npm run build"
        timeout: 120

Webhook URL:POST /webhook/github-deploy

场景 2:GitLab CI 流水线完成通知

name: "gitlab-notify"
auth:
  token:
    source: "header"
    key: "X-Gitlab-Token"
    value: "your-gitlab-token"
execution:
  policy: "always"
rules:
  - name: "pipeline-success"
    filters:
      - type: "header"
        key: "X-Gitlab-Event"
        operator: "eq"
        value: "Pipeline Hook"
      - type: "body"
        key: "object_attributes.status"
        operator: "eq"
        value: "success"
    actions:
      - type: "command"
        cmd: "curl -s https://slack.com/api/chat.postMessage -d 'text=Pipeline succeeded!'"
        timeout: 10

场景 3:限频部署

name: "rate-limited-deploy"
execution:
  policy: "cooldown"
  cooldown_seconds: 600    # 最多每 10 分钟一次
rules:
  - name: "deploy"
    filters:
      - type: "header"
        key: "X-Event"
        operator: "eq"
        value: "deploy"
    actions:
      - type: "script"
        path: "/opt/scripts/deploy.sh"
        args: ["production"]
        timeout: 300
        isolate: true

场景 4:单文件多环境

name: "multi-env-deploy"
execution:
  policy: "block"
rules:
  - name: "deploy-staging"
    filters:
      - type: "body"
        key: "ref"
        operator: "eq"
        value: "refs/heads/develop"
    actions:
      - type: "command"
        cmd: "deploy.sh staging"
        timeout: 120

  - name: "deploy-production"
    execution:
      policy: "cooldown"
      cooldown_seconds: 1800    # 生产环境 30 分钟冷却
    filters:
      - type: "body"
        key: "ref"
        operator: "eq"
        value: "refs/heads/main"
    actions:
      - type: "command"
        cmd: "deploy.sh production"
        timeout: 300

场景 5:强制使用定向路由

禁用基础路由遍历,要求明确指定目标:

# config.yaml
server:
  port: 9000
  route: "/webhook"
  allow_all: false    # 必须使用 /webhook/{filename}

所有请求 /webhook 的请求返回 400。客户端必须使用:

POST /webhook/frontend
POST /webhook/backend
POST /webhook/api

场景 6:多服务器 Relay 部署

通过静态目标和动态 Tag 匹配,将 Webhook 从中心 HookRun 转发到多个下游实例:

# 上游(主 HookRun)— hooks/deploy-app.yaml
name: "deploy-app"
execution:
  policy: "block"
rules:
  - name: "relay-to-servers"
    filters:
      - type: "body"
        key: "ref"
        operator: "regex"
        value: "refs/heads/main"
    actions:
      - type: "relay"
        relay:
          targets:
            - url: "http://10.0.0.2:9000/webhook/deploy-app"   # 静态目标
              token: "relay-secret-B"
            - tag: "prod"                                      # 动态:所有带 "prod" 标签的已注册目标
          forward_headers:
            - "X-GitHub-Event"
          timeout: 30
          max_relay_hops: 3
# 上游 config.yaml — 启用 Relay Registry 实现动态发现
server:
  port: 9000
  relay_registry_token: "your-registry-secret"
  max_relay_ttl: 300
  max_registry_entries: 100

下游实例启动时自动注册并维持心跳:

# 下游(10.0.0.2)config.yaml
server:
  port: 9000

relay_client:
  upstream: "http://main-hookrun:9000"
  url: "http://10.0.0.2:9000/webhook/deploy-app"
  token: "relay-secret-B"
  registry_token: "your-registry-secret"
  tags: ["prod"]
  ttl: 120

场景 7:自注册 Relay 客户端

下游 HookRun 实例启动时自动向上游注册并发送周期性心跳,无需手动操作:

# 下游 config.yaml
server:
  port: 9000

relay_client:
  upstream: "http://main-hookrun:9000"          # 上游 URL(必填)
  url: "http://10.0.0.5:9000/webhook/deploy-app" # 本地可达 URL
  token: "my-auth-token"                         # Relay 转发时的认证 Token
  registry_token: "your-registry-secret"         # Registry API Bearer Token
  tags: ["web", "prod"]                          # 目标匹配标签
  ttl: 120                                       # TTL(秒)
  webhook_path: "/webhook/deploy-app"            # 用于 URL 自动探测
  • 启动时自动发送 POST /api/relay/register 到上游
  • ttl / 3 秒发送心跳保活
  • 优雅关闭时发送 DELETE /api/relay/register 注销
  • 若省略 url,则从本地 IP + 端口 + webhook_path 自动探测

5. 日志

Daily 模式(默认)

  • 日志写入 {log.path}/hookrun-YYYY-MM-DD.log
  • 每天创建新文件
  • 启动时自动删除超过 retention_days 的过期日志

Single 模式

  • 日志写入 {log.path}/hookrun.log
  • 固定单文件,可按大小轮转(max_size_mb
  • 适合容器环境或外部日志管理

规则级日志

  • 每个规则配置可指定 log.path 写入独立日志文件
  • 日志双写到全局日志和规则专属日志

每次 Webhook 请求和执行结果都带时间戳记录。


6. 配置校验最佳实践

  1. 启动前务必校验

    hookrun validate && hookrun start
    
  2. 编辑后校验

    # 编辑 YAML 文件
    vim hooks/my-app.yaml
    # 校验(不重载)
    hookrun validate
    # 校验通过后重载
    hookrun reload
    
  3. 调试时使用前台模式

    hookrun start -f
    

    所有日志直接输出到终端,方便实时排查。