配置指南
Thurgio 常见用例的实际配置模式。
最小工作配置
每个 Thurgio 设置至少需要一个 provider(提供者),在 provider.yaml 中定义获取、处理与渲染所需的一切:
# thurgio.yaml
setting:
tokens:
admin:
- "your-api-token" # 至少配置一个令牌
output:
provider:
"clash_list.tpl":
- "output/proxies.yaml" # 默认输出路径(按模板名映射,详见配置参考)
# provider.yaml
example:
name: example
type: clash
source: "https://example.com/clash-config"
template: clash_list.tpl
filename:
- output/proxies.yaml
管道流程为:Provider → 获取 → 解析代理 → pre_rename → filter → rename → 使用模板渲染 → 写入输出。
添加多个提供者
你可以从多个来源聚合代理:
# provider.yaml
vps_provider:
name: vps_provider
type: clash
source: "https://example.com/clash-config"
template: clash.tpl
filename:
- output/vps.yaml
rename:
- "add_vps_prefix"
free_provider:
name: free_provider
type: sip002
source: "https://example.com/sip002.txt"
template: sip002.tpl
filename:
- output/free.txt
local_backup:
name: local_backup
type: v2rayn
source: "backup/v2rayn.json"
template: v2rayn.tpl
filename:
- output/backup.txt
支持的提供者类型(provider.type):
| 类型 | 描述 |
|---|---|
clash | Clash YAML 格式 |
meta | Clash.Meta YAML 格式 |
v2rayn | V2RayN 分享链接格式(Base64 JSON 数组) |
sip002 | SIP002 URI 格式(逐行 ss:// 等) |
sip008 | SIP008 JSON 订阅格式(Shadowsocks Android,version+servers) |
surge | Surge 配置格式(解析 [Proxy] 段) |
qx | Quantumult X 节点行(shadowsocks=/vmess= 等 7 种) |
loon | Loon 节点行(10 种) |
ssd | SSD 订阅格式(ssd:// Base64 JSON 文档) |
singbox | sing-box 配置 JSON(解析 outbounds 数组,基础字段,含 wireguard/naive/ssh) |
telegram | TG 类 HTTP/SOCKS5 代理链接(tg://http / tg://socks / t.me/* → Http/Socks5) |
auto | 仅渲染侧 tpl=auto 的辅助值(provider type 仍需显式指定真实输入格式;auto 由服务端 UA 探测选模板) |
每个 provider 独立渲染自己的输出;同一个提供者可以通过 outputs 定义多个具名输出,用不同模板渲染同一份代理列表:
# provider.yaml
all_proxies:
name: all_proxies
type: clash
source: "https://example.com/clash-config"
template: clash.tpl
filename:
- output/clash.yaml
rename:
- "clean_names"
outputs:
v2rayn:
template: v2rayn.tpl
filename:
- output/v2rayn.txt
过滤代理
过滤规则按名称保留或剔除代理。在 filter.yaml 中定义过滤规则(声明式语法,详见配置参考):
filter:
# 简写:包含任一关键字的代理(忽略大小写)
only_uk_us: "英国|美国|UK|US|London|New York"
# 仅保留 ss 类型
ss_only:
- type: ss
# 正则
hk:
- regex: '\W+(US|us|United States)\W+'
在提供者中引用过滤规则:
# provider.yaml
my_list:
name: my_list
type: clash
source: "https://example.com/proxy-config"
template: clash.tpl
filter:
- "only_uk_us"
- "ss_only" # 多个过滤规则依次应用
匹配器
| 匹配器 | 值 | 匹配条件… |
|---|---|---|
contain | 字符串或字符串数组 | 名称包含任一关键字(数组 = OR;默认忽略大小写) |
start | 字符串 | 名称以关键字开头 |
end | 字符串 | 名称以关键字结尾 |
type | 字符串 | 代理类型(ss、vmess 等) |
regex | 字符串 | 代理名称匹配正则表达式 |
共享选项:ignore_case(缺省 true)、negate(缺省 false,命中则剔除)。列表(AND)仅支持 contain/start/end。
重命名代理
重命名规则使用正则替换(支持反向引用)清理或标准化代理名称:
rename:
add_vps_prefix:
- "^(.*)$"
- "VPS-$1"
clean_names:
- "(美国)"
- "🇺🇸 US"
- "(日本)"
- "🇯🇵 JP"
- "带宽.*"
- "Standard"
room_number:
- "(\\d+)-(\\d+)"
- "$1-$2" # 支持正则反向引用
在提供者中应用(pre_rename 在过滤前、rename 在过滤后):
# provider.yaml
my_provider:
name: my_provider
type: clash
source: "https://..."
template: clash.tpl
pre_rename: # 在过滤前应用(解析后立即执行)
- "add_vps_prefix"
rename: # 在过滤后应用
- "clean_names"
- "room_number"
每条规则是 [正则, 替换串] 列表,对代理名称执行 replace_all。
使用 Emoji 模式
Emoji 模式根据检测到的国家/地区自动在代理名称前添加旗帜 emoji。
全局设置
setting:
mode: Enable # 全局启用 emoji(默认值)
其他可选值:
| 值 | 效果 |
|---|---|
Disable | 不添加 emoji 前缀 |
Enable | 检测到国家/地区时添加旗帜 emoji 前缀(默认) |
Hide | 去除代理名称中已有的 emoji 前缀 |
按提供者覆盖
为特定提供者覆盖全局设置:
# provider.yaml
my_provider:
name: my_provider
type: clash
source: "https://..."
template: clash.tpl
emoji: false # 仅对此提供者禁用 emoji(默认 true)
模板示例
模板使用 Tera 引擎(语法类似 Jinja2/Django)。
上下文变量
| 变量 | 可用范围 | 描述 |
|---|---|---|
l.proxies | provider、具名输出 | 代理对象列表 |
l.name | provider、具名输出 | 当前 provider 的名称 |
l.rename | provider、具名输出 | 当前 provider 的重命名规则(键名) |
l.filter | provider、具名输出 | 当前 provider 的过滤规则(键名) |
s.response.content | snippet | 当前 snippet 的源内容(原样文本);adhoc snippet 绑定为 content |
p.* | 全部 | 来自配置的自定义参数(params.yaml + /app/admin/p 热更新) |
hp.* | 全部 | 本次 HTTP 请求的查询参数(与 p 分离;无请求参数时为 {}) |
config | 全部 | 完整配置对象(config.snippet、config.params、config.setting 等) |
headers | 全部 | 请求头映射(HTTP API 渲染时) |
version | 全部 | 版本字符串 |
now() | 全部 | 当前时间戳(Tera 函数) |
get_env(name=..., default=...) | 全部 | 读取环境变量(Tera 函数) |
自定义过滤器(30+,register_all 统一注册)
| 过滤器 | 描述 |
|---|---|
slugify(separator="-") | 字符串 slug 化 |
urlencode() | URL 编码 |
indent(width=2, first=false, blank=false) | 缩进内容 |
json() / yaml() | 将字符串解析为 JSON/YAML 值 |
json_str(pretty=true) | 将代理序列化为紧凑或美观的 JSON |
yaml_str() | 将代理列表序列化为 YAML |
to_yaml_vec() | 逐行转为 YAML 列表 |
clear(num=3, n=2) | 压缩连续空行 |
uniq() | 按行去重 |
base64(mode="encode", config=...) | Base64 编码/解码 |
clash(symbol=..., policy=...) | 格式化为 Clash 代理条目(单条规则文本输入) |
cla(meta=true) | Clash 代理条目(数组输入,V2rayN/Sip002 已按能力谓词过滤) |
surge(symbol=..., policy=...) | 格式化为 Surge 代理条目(单条规则文本输入) |
surge_proxy() | 代理数组 → Surge [Proxy] 段行(ss/trojan/vmess/snell/http/socks5/wireguard 8 种) |
qx() | 代理数组 → Quantumult X 节点行(ss/ssr/vmess/vless/trojan/http/socks5 7 种) |
qx_config(check_url=, dns=, group=) | 代理数组 → 完整 Quantumult X 配置四段([general]/[dns]/[server_local]/[policy]) |
loon() | 代理数组 → Loon 节点行(10 种) |
loon_config(dns=, group=) | 代理数组 → 完整 Loon 配置四段([General]/[Proxy]/[Proxy Group]/[Rule]) |
mellow(port=1080) | 代理数组 → Mellow/V2Ray-core JSON(socks inbound + per-proxy outbounds,ss/vmess/vless/trojan/http/socks5 + TCP/WS/TLS) |
mixed() | 代理数组 → 混合单链接列表(V2RayN 优先、SIP002 回退逐节点分发) |
stash() | 代理数组 → Stash(Clash 兼容)节点行 |
surfboard() | 代理数组 → Surfboard(Surge 兼容)节点行 |
clashr() | 代理数组 → ClashR 节点行 |
ssd() | 代理数组 → ssd:// 订阅(仅 ss) |
sip008() | 代理数组 → SIP008 JSON 订阅(仅 ss) |
shadowrocket() | 代理数组 → Shadowrocket 分享链接(复用 sip002/v2rayn,wg 跳过) |
quantumult(symbol=..., policy=...) | 格式化为 Quantumult X 规则集(host/host-suffix/host-keyword/ip-cidr/ip6-cidr/geoip/user-agent/final;MATCH→final) |
singbox(pretty=true, policy=...) | 格式化为 sing-box 代理条目(单条规则文本输入) |
sibox() / singbox() | 代理数组 → sing-box outbound 对象数组(12 变体,TryFrom<ProxyTy> 单向) |
clashbox(premium=..., meta=...) | clash 规则文本 → sing-box rule 对象数组 |
v2rayn() | 代理数组 → V2RayN 分享链接(V2RAYN_CAPABILITIES 5 种仅元类型) |
sip002() | 代理数组 → SIP002 URL(除 WireGuard 外全部) |
proxy_suffix(suffix=...) | 在代理名称后添加协议后缀 |
js(src="...") | 代理数组 → 内联 JS 变换($input 全局,boa_engine,须显式 return) |
sort_nodes(by=name/region/latency, order=asc/desc, latencies=...) | 代理数组 → 按 name/region/latency 排序 |
clash_groups / surge_groups | 代理数组 → Clash/Surge 策略组(select + 按地区 url-test) |
ruleset(name=, format=clash/surge, text=) | 命名规则集格式化(内联 text > _rules.ruleset > 内置 assets/rulesets/*.list) |
no_resolve(symbol=..., value=...) | 标记带 no-resolve 的代理 |
sort_domain_ip(symbol=...) | 按域名/IP 排序代理规则 |
rule(symbol=..., policy=...) | 应用路由规则 |
fil() | 应用额外的过滤(clash/surge/cla/v2rayn/sip002) |
filter(rules=...) | 按配置的过滤规则动态过滤代理(rules 为 filter.yaml 中的规则名,逗号分隔或数组,_rules.filter 表) |
rename(rules=...) | 按配置的重命名规则动态改名(rules 为 rename.yaml 中的规则名,_rules.rename 表) |
示例:带测试部分的 Clash 输出
{# tpls/clash.tpl #}
{%- set format = "json" -%}
{%- set pretty = false -%}
# {{ l.name }}
# 生成时间 {{ now() | date(format="%Y-%m-%d %H:%M:%S") }}
test: &test
url: {{ p.test.url }}
interval: {{ p.test.interval }}
proxies:
{% filter indent(width=2) %}{% if format == "json" %}
{%- for i in l.proxies %}
- {{ i | json_str(pretty=pretty) }}
{%- endfor %}{% elif format == "yaml" %}
{{ l.proxies | yaml_str() }}{% endif %}{% endfilter %}
示例:V2RayN 输出
{# tpls/v2rayn.tpl #}
{{ l.proxies | v2rayn() }}
示例:模板内动态应用过滤/重命名规则
模板可在 l.proxies 基础上按需应用 filter.yaml / rename.yaml 中的规则,多个过滤器可链式组合(顺序即应用顺序):
{# 只保留美国节点,去掉名称中的 "US-" 前缀,再输出 V2RayN 格式 #}
{{ l.proxies | filter(rules="us") | rename(rules="us_prefix") | v2rayn() }}
rules 参数接受逗号分隔的规则名字符串或名字数组;未定义的规则名会被静默忽略(与配置解析行为一致)。
示例:SIP002 输出
{# tpls/sip002.tpl #}
{{ l.proxies | sip002() }}
使用自定义参数
在配置中定义参数:
params:
test:
url: "http://www.gstatic.com/generate_204"
interval: 600
region: "asia"
然后在模板中使用:
test-url: {{ p.test.url }}
test-interval: {{ p.test.interval }}
region: {{ p.region }}
使用 config.snippet
片段可以为模板提供额外数据:
snippet:
ruleset:
source:
url: "https://example.com/rules.yaml"
p:
clash_url: "https://example.com/clash-rules.yaml"
在模板中:
{%- for k, v in config.snippet %}
rule-provider {{ k }}:
url: {{ v.p.clash_url }}
{%- endfor %}
TLS 设置
通过 TLS 提供 HTTPS 代理服务。
使用 CLI 标志
thurgio serve \
--tls-only \ # 仅提供 HTTPS(无明文 HTTP)
--tls-port 8443 \ # TLS 端口
--tls-cert /etc/ssl/cert.pem \ # 证书文件(-c)
--tls-cert-key /etc/ssl/key.pem # 私钥文件(-k)
TLS + 明文在不同端口上
thurgio serve \
--port 10100 \ # 明文 HTTP
--tls-port 8443 \ # 同时提供 HTTPS
--tls-cert /etc/ssl/cert.pem \
--tls-cert-key /etc/ssl/key.pem
注意:
--tls-port默认等于--port。同时提供明文与 HTTPS 时必须显式指定不同的 TLS 端口,否则两个服务会绑定同一地址导致启动失败。
使用环境变量
export TLS_CERT=/etc/ssl/cert.pem
export TLS_CERT_KEY=/etc/ssl/key.pem
export TLS_PORT=8443
export TLS_ONLY=true
thurgio serve
拆分配置为多个文件
Thurgio 解析 thurgio.yaml 后,会自动读取配置文件所在目录下的配套 YAML 文件并合并(模板目录同样相对该目录解析,ADR-066):
| 文件 | 配置段 | 缺失时 |
|---|---|---|
provider.yaml | provider | 合并空 |
params.yaml | params | 合并空 |
rename.yaml | rename | 报错(必须存在空或有内容) |
filter.yaml | filter | 报错 |
snippet.yaml | snippet | 合并空 |
ruleset.yaml | ruleset | 合并空(唯一缺失合法的 sibling,ADR-086):本地行列表或 http(s):// 远程 URL(更新管线物化进 _rules.ruleset) |
这对于组织大型配置很有用:
~/.config/thurgio/
├── thurgio.yaml # 主配置(setting)
├── provider.yaml # 所有提供者
├── filter.yaml # 所有过滤规则
├── rename.yaml # 所有重命名规则
├── snippet.yaml # 所有片段
└── tpls/ # 模板目录(THURGIO_TPL_DIR,默认 "tpls")
├── clash.tpl
├── surge.tpl
└── v2rayn.tpl
所有被引用的模板文件必须在模板目录中存在,否则配置解析失败。
命名规则集(ruleset.yaml)
可选 sibling 文件 ruleset.yaml 按名称定义命名规则集(本地行列表或 http(s):// 远程 URL),生成 _rules.ruleset 上下文面供 ruleset 过滤器消费({{ l.proxies | ruleset(name="ads") }})。远程条目由更新管线定时拉取并物化,本地声明优先于同名远程。
# ruleset.yaml
ads:
- DOMAIN-SUFFIX,ads.example.com
- DOMAIN-KEYWORD,tracker
cnlist: https://example.com/cn.list
过滤器调用:{{ l.proxies | ruleset(name="ads", format="clash") }} / surge;内联 text 参数优先于命名表,命名表优先于内置 assets/rulesets/*.list。
备份与回滚
编辑配置前可以用 config backup 把当前声明文件(thurgio.yaml、5 个 sibling YAML 与 tpls/ 模板目录,清单与配置热重载的监听一致;ruleset.yaml 不在清单内)整体复制到备份目录:
thurgio config backup
# ✔ Backup created: <root>/backups/20260814-153000
thurgio config list
# Available backups in <root>/backups:
# 20260814-153000 2026-08-14 15:30:00
默认备份到 <root>/backups/<YYYYMMDD-HHMMSS>/,可用 -d/--dir 指定其他位置;只复制实际存在的文件。
配置改坏后,用 list 找到备份名并恢复:
thurgio config restore 20260814-153000
restore 接受备份名(backups/ 下的子目录名)或备份目录路径(绝对路径,或相对 root 的路径)。恢复前会把当前状态自动再备份一份到 backups/(保险),然后覆盖写回声明文件与 tpls/;仅恢复备份中包含的内容,不会删除 root 中的其他文件。
数据库
Thurgio 使用嵌入式 SQLite 数据库(WAL 模式)进行持久化,无需外部数据库服务器。数据库文件(默认 thurgio.db,可用 DATABASE_URL 环境变量覆盖;兼容 sqlite:// 前缀写法)会在首次使用时自动创建于工作目录。持久化以下数据:
- Provider 响应 — 缓存的响应,避免每次构建时重新获取。
- Snippet 数据 — 获取的片段内容。
- 熔断器快照 — 重启后保持打开状态的熔断器。
- KV 存储 — 通用键值数据(
kv_store表)。
环境变量参考
| 变量 | 覆盖项 | 默认值 |
|---|---|---|
ROOT | 工作根目录(-r/--root) | 当前目录 |
FORCE | build 强制更新(-f/--force) | false |
WATCH | build 监听模式(-w/--watch) | false |
NOTIFY | build 完成时发送系统通知(-N/--notify) | false |
SHELL | generate 补全目标 shell(-s/--shell) | bash |
OUTPUT | generate 输出文件(-o/--output) | stdout |
ADDRESS | serve 监听地址(-a/--address) | 配置 setting.address(默认 0.0.0.0) |
PORT | serve 监听端口(-p/--port) | 配置 setting.port(默认 10100) |
DEV | serve 开发模式(-d/--dev) | false |
IDLE | serve 空闲模式(-i/--idle):无请求时自动退出 | false |
EVICT | serve 空闲时清空数据缓存(-e/--evict) | true |
TLS_ONLY | serve 仅提供 HTTPS(-s/--tls-only) | false |
TLS_PORT | serve TLS 端口(-t/--tls-port) | 同 PORT |
TLS_CERT | TLS 证书路径(-c/--tls-cert) | 无 |
TLS_CERT_KEY | TLS 私钥路径(-k/--tls-cert-key) | 无 |
OPEN | serve 启动时打开浏览器(-O/--open) | false |
THURGIO_CONCURRENCY_LIMIT | 并发限制(渲染/持久化任务) | 10 |
THURGIO_TPL_DIR | 模板目录 | tpls |
THURGIO_RENDERER_RELOAD_TIMEOUT | 渲染器重载超时(秒) | 3 |
THURGIO_RENDERER_MIN_THREADS | 渲染线程池最小线程数 | 1 |
THURGIO_RENDERER_MAX_THREADS | 渲染线程池最大线程数 | 64 |
THURGIO_RENDERER_IDLE_TIMEOUT | 渲染线程空闲退出时间(秒) | 5 |
THURGIO_RENDERER_IDLE_COOLDOWN | 缩容冷却次数 | 3 |
THURGIO_RENDERER_SCALE_UP_THRESHOLD | 扩容阈值(平滑 backlog 倍数) | 2.0 |
THURGIO_RENDERER_SCALE_DOWN_THRESHOLD | 缩容阈值 | 0.5 |
THURGIO_RENDERER_EMA_ALPHA | backlog EMA 平滑系数 | 300 |
THURGIO_WEBHOOK_URL | 构建完成通知 webhook(POST JSON) | 无(禁用) |
EVICT_TIMEOUT | 空闲后清空数据缓存的等待时间(秒,--evict 开启时) | 10 |
IDLE_TIMEOUT | 空闲模式退出等待时间(秒,--idle 开启时) | 30 |
DATABASE_URL | 数据库文件路径 | thurgio.db |
REQUEST_TIMEOUT | HTTP 客户端请求超时(秒) | 9 |
THURGIO_MAX_CONCURRENT_REQUESTS | 服务器最大并发请求数 | 600 |
THURGIO_RATE_LIMIT_REQUESTS | 每个 IP 时间窗内最大请求数 | 600 |
THURGIO_RATE_LIMIT_WINDOW_SECONDS | 速率限制时间窗(秒) | 60 |
THURGIO_MAX_RATE_LIMIT_ENTRIES | 速率限制条目上限 | 10000 |
RUST_LOG | 日志级别过滤(如 info,thurgio=debug) | info |
RUST_LOG_ANSI | 是否启用日志颜色(true/false) | 自动检测(stdout 为 TTY) |
RUST_LOG_FORMAT | 日志格式(json 启用 JSON 输出) | 文本 |
RUST_INVALID_TLS | 跳过 TLS 证书校验(仅测试用) | false |
OTEL_EXPORTER_OTLP_ENDPOINT | OTLP 导出端点(otlp 特性,gRPC) | http://localhost:4317 |