跳转到内容

核心概念

Raddexfile 是 raddex 的核心:一份纯文本配置,采用 Caddyfile 风格的语法,用 raddex check 校验、用 raddex run 服务。本页给你心智模型;指令 参考有完整语法,站点 · 端口 · HTTPS介绍请求如何匹配到 站点。

一份 Raddexfile 由一个可选的全局块和若干站点块组成:

{
acme_email ops@example.com
}
api.example.com {
reverse_proxy 127.0.0.1:8080
}
static.example.com {
root /var/www/html
file_server
}
  • 全局块 —— 文件顶部的裸 { ... } —— 承载站点级设置,例如你的 ACME 邮箱。
  • 每个站点块把一个主机(可选带端口)映射到行为。

请求匹配到站点后,raddex 严格按书写顺序执行该站点的每一行。每行要么是 终端、修饰符,要么是守卫:

  • 终端指令决定由谁服务请求:reverse_proxy、file_server、redir、 respond、error。第一个匹配的终端结束站点——后续行不再执行。终端 可携带内联匹配器;不匹配的终端是空操作,执行继续。
  • 修饰指令描述如何服务,与位置无关:header_up、header_down、 encode、rewrite。它们作用于服务该块的终端,即使写在终端之后。
  • 守卫指令决定谁可以被服务:rate_limit、basic_auth、forward_auth。 它们像修饰指令一样——作用于服务该块的任意终端——并在守卫失败时拒绝请求 (429、401)。

Caddy 用户: Caddy 会在后台重排指令顺序;raddex 不会。顺序由你控制, 第一个匹配者胜出。

匹配器选择哪些请求由指令服务

Section titled “匹配器选择哪些请求由指令服务”

匹配器是一组匹配项——path、host、method、header、 query、remote_ip、protocol——必须全部匹配。匹配器附着在 handle 块上, 也可内联附着在终端上:

handle path /status method GET {
respond 200 ok
}

各项以空格分隔并 AND;没有括号或 &&。handle /static/* 是 handle path /static/* 的简写。

handle <matcher> { ... } 是作用域块:若匹配器匹配,块内行执行并停止匹配; 否则跳过继续。可以理解为“这些请求,用这个终端”。handle_path 与之相同, 只是会在块内终端运行前剥离被匹配的路径前缀。

把模型放到一个具体站点上:

api.example.com {
handle /static/* {
root /var/www/html
file_server
encode zstd gzip
}
reverse_proxy 127.0.0.1:8080
rate_limit remote_ip 100r/s
header_up X-Real-IP {remote_host}
}

请求:GET /static/app.js

  1. handle /static/* 匹配该路径,因此块内行按序执行。
  2. root 设置目录;file_server 服务 /var/www/html/static/app.js 并 结束站点执行。
  3. encode zstd gzip —— 块内的修饰指令 —— 在客户端接受时压缩响应。
  4. 站点级修饰指令(rate_limit、header_up)同样作用于这个终端,因为站点级 修饰指令作用于服务该块的任意终端。rate_limit 检查该客户端的令牌桶; header_up 面向上游请求,对本地文件无效果。

请求:GET /api/users

  1. handle /static/* 不匹配,执行继续。
  2. reverse_proxy 没有匹配器,总是匹配,于是代理到 127.0.0.1:8080,结束 站点。
  3. rate_limit remote_ip 100r/s 同样守卫这个终端(它是站点级修饰指令)。桶空 时返回 429 Too Many Requests。
  4. header_up X-Real-IP {remote_host} 把客户端 IP 加入上游请求头。

书写顺序只在终端之间有意义。修饰指令无论写在哪里都生效,按其作用域: 站点级修饰指令作用于站点内每个终端;handle 块内的修饰指令只作用于该块 的终端。