Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

部署指南

使用 systemd、Docker 或反向代理在生产环境中运行 Thurgio。


从 GitHub Release 安装二进制

Thurgio 不发布包管理器制品;release 二进制由 CI 构建并上传到 GitHub Releases,同时发布私有 Docker 镜像(见 使用 Docker)。每个 release 包含各架构的二进制与配套校验文件,资产名带目标架构后缀:thurgio-<target>thurgio-<target>.sha256

目标架构适合场景Release 资产
x86_64-unknown-linux-musl绝大多数 x86_64 Linux 服务器thurgio-x86_64-unknown-linux-musl
aarch64-linux-androidAndroid 设备(不是服务器)thurgio-aarch64-linux-android
aarch64-unknown-linux-muslARM64 Linux 服务器(如树莓派)自行构建:just build-arm-linux

Release 目前只附带 x86_64-unknown-linux-muslaarch64-linux-android 两个构建产物(见 .github/workflows/ci.yml)。ARM64 服务器用户请用仓库内 just build-arm-linux 交叉编译,或查看 交叉编译 章节。

下载并校验(<tag> 替换为版本号,如 v0.18.0;下面以 x86_64 Linux 服务器为例,Android 设备把 ARCH 换成 aarch64-linux-android):

TAG=v0.18.0
ARCH=x86_64-unknown-linux-musl
curl -fLO "https://github.com/xylylab/thurgio/releases/download/${TAG}/thurgio-${ARCH}"
curl -fLO "https://github.com/xylylab/thurgio/releases/download/${TAG}/thurgio-${ARCH}.sha256"

# 校验 sha256;校验文件记录的文件名是构建时的 `thurgio`,先改名再校验,
# 输出 `thurgio: OK` 才说明二进制与 release 一致
mv thurgio-${ARCH} thurgio
sha256sum -c thurgio-${ARCH}.sha256

sudo install -m 0755 thurgio /usr/local/bin/thurgio
thurgio version

install 会把二进制安装为 root 所有(systemd 单元以专用用户运行二进制,见下节)。若仓库 fork 或迁移,替换上面 URL 中的 xylylab/thurgio 为实际仓库。


作为 systemd 服务

创建一个 systemd 单元来将 Thurgio 作为长期运行的后台服务管理。

1. 创建专用用户

sudo useradd -r -s /usr/sbin/nologin -m -d /var/lib/thurgio thurgio

2. 放置二进制文件

sudo cp thurgio /usr/local/bin/thurgio
sudo chown thurgio:thurgio /usr/local/bin/thurgio

3. 创建配置目录

sudo mkdir -p /etc/thurgio/tpls
sudo chown -R thurgio:thurgio /etc/thurgio

4. 编写配置文件

# /etc/thurgio/thurgio.yaml
setting:
  tokens:
    admin:
      - "your-production-token"       # 使用强随机令牌
  address: "127.0.0.1"                # 绑定到 localhost;反向代理处理公网访问
  port: 10100
  output:
    provider:
      "clash.tpl":
        - "output/proxies.yaml"
# /etc/thurgio/provider.yaml
my_provider:
  name: my_provider
  type: clash
  source: "https://example.com/clash-config"
  template: clash.tpl
  filename:
    - output/proxies.yaml

5. 创建 systemd 单元

仓库提供了一份带注释与安全加固的单元文件,直接复制即可:

sudo install -m 644 deploy/systemd/thurgio.service /etc/systemd/system/thurgio.service

关键设置说明(完整注释见文件本身):

  • ExecStart=/usr/local/bin/thurgio -c /etc/thurgio/thurgio.yaml -r /var/lib/thurgio serveserve 在前台运行(无 daemon 模式),配合 Type=simple 由 systemd 直接管理进程;Restart=always + RestartSec=5s 在崩溃或空闲退出(--idle)时自动拉起,StartLimitIntervalSec/StartLimitBurst 防 crash 循环。
  • -r /var/lib/thurgio 会把工作目录切换到数据根目录:thurgio.dbDATABASE_URL 默认值)与配置中的相对输出路径都相对它解析。
  • 拆分 YAML(provider.yaml/params.yaml/rename.yaml/filter.yaml/snippet.yaml)与模板目录则相对 thurgio.yaml 所在目录 解析(即 /etc/thurgio),与 -r 无关。
  • Environment=DATABASE_URL=/var/lib/thurgio/thurgio.db 显式指定数据库位置;RUST_LOG=info 控制日志级别(默认即 INFO);模板目录默认 tpls(相对配置目录),只有模板不在默认位置时才需要设置 THURGIO_TPL_DIR
  • 硬化:NoNewPrivilegesProtectSystem=strict(仅 ReadWritePaths=/var/lib/thurgio 可写)、ProtectHomePrivateTmp/PrivateDevicesRestrictSUIDSGIDRestrictAddressFamiliesUMask=0027 等。
  • 空闲退出(--idle:最后一个请求完成 30 秒(IDLE_TIMEOUT)后无新请求时进程正常退出,Restart=always 会在下一个请求到达时自动拉起——这正是 idle 模式的设计语义(配合缓存降级 --evict,空闲 10 秒先清空数据缓存)。

6. 启动并启用

sudo systemctl daemon-reload
sudo systemctl enable --now thurgio

7. 验证与健康检查

sudo systemctl status thurgio

# 就绪探测:/ready 是公开端点(无需 token),数据库可应答时返回
# 200 {"status":"ready",...},否则 503;curl -f 对非 2xx 退出非零
curl -fsS http://127.0.0.1:10100/ready

/ready 与 Docker 镜像内置的 HEALTHCHECK 使用同一端点(见下文),适合接入负载均衡器或外部监控。/health 是另一个公开端点,返回版本、数据库状态与内存占用等更详细的信息。

8. 查看日志

服务日志输出到 stdout/stderr,由 journald 收集:

journalctl -u thurgio -f          # 跟随最新日志
journalctl -u thurgio -n 200      # 最近 200 行
journalctl -u thurgio --since "1 hour ago"

需要结构化日志时,在单元中设置 Environment=RUST_LOG_FORMAT=json

9. 日志轮转

journald 自带容量与轮转管理(journalctl --vacuum-* 可手动清理),无需额外配置。仅当你自行把日志重定向到文件时才需要 logrotate,示例:

# /etc/logrotate.d/thurgio
/var/log/thurgio/*.log {
    daily
    rotate 30
    compress
    delaycompress
    missingok
    notifempty
    copytruncate
}

10. 升级

# 1. 下载新版本二进制并校验(见上方「从 GitHub Release 安装二进制」)
sudo systemctl stop thurgio
sudo install -m 0755 thurgio /usr/local/bin/thurgio
sudo systemctl start thurgio

# 2. 确认新版本与健康状态
thurgio version
sudo systemctl status thurgio
curl -fsS http://127.0.0.1:10100/ready

数据库与输出文件都位于 /var/lib/thurgio,替换二进制不影响数据;/etc/thurgio 配置不动,无需迁移。也可以运行 thurgio upgrade 检查是否有新版本(它只检查并打印下载地址,不会自动安装)。


使用 Docker

仓库根目录提供多阶段 Dockerfile,可直接从源码构建;CI 也会把镜像发布为 GHCR 私有包 ghcr.io/xylylab/thurgio(默认 private,见 发布私有镜像):

  • build 阶段rust:alpine(默认 musl 目标,直接产出静态二进制);先复制 Cargo.toml/Cargo.lock/crates/ 以缓存依赖编译层,再以 cargo build --release --locked -p thurgio-cli 编译;
  • runtime 阶段alpine:latest + ca-certificates(HTTPS 抓取订阅需要根证书)+ tzdata,仅复制二进制。

拉取私有镜像

GHCR 包默认私有,拉取前需要登录(一次性):

# GitHub CLI:输出登录 token 给 docker login
docker login ghcr.io --username <你的 GitHub 用户名>
# 提示输入密码时粘贴以下命令的输出:
gh auth token

# 或使用 PAT(需要 read:packages scope)
docker login ghcr.io --username <你的 GitHub 用户名> --password-stdin <<< "<PAT>"

登录后即可拉取:

docker pull ghcr.io/xylylab/thurgio:v0.18.0   # 或 :latest

从源码构建镜像

docker build -t thurgio:latest .
# 或 just docker-build

.dockerignore 已排除文档、设计文件与构建产物,上下文只包含构建所需的 Cargo.toml/Cargo.lock/crates/fuzz/Cargo.tomlfixtures/examples/tpls/thurgio-cli 编译期嵌入该模板)。

运行容器

镜像的目录约定:

路径用途
/config(只读挂载)配置目录:thurgio.yaml 及其拆分的 provider.yaml/filter.yaml/rename.yaml/snippet.yaml、模板 tpls/
/data(卷)数据目录:SQLite 数据库(DATABASE_URL,默认 /data/thurgio.db)与渲染输出
# 私有镜像(已登录 GHCR):
docker run -d \
  --name thurgio \
  -p 127.0.0.1:10100:10100 \
  -v "$PWD/config:/config:ro" \
  -v thurgio-data:/data \
  ghcr.io/xylylab/thurgio:latest

# 或本地构建的镜像:
docker run -d \
  --name thurgio \
  -p 127.0.0.1:10100:10100 \
  -v "$PWD/config:/config:ro" \
  -v thurgio-data:/data \
  thurgio:latest
  • 默认命令为 -r /config serve-r 会切换到配置根目录,thurgio.yaml-c 默认值)及其拆分文件、模板都相对 /config 解析。
  • 输出路径:配置中的输出路径请使用 /data/... 绝对路径(相对路径会落在 /config 只读卷上,导致写入失败)。
  • 环境变量(CLI 参数均支持环境变量注入):DATABASE_URL(数据库位置,默认 /data/thurgio.db)、ROOT(等价于 -r/--root)、ADDRESS/PORT(监听地址/端口)、TZ(时区)。注意 -c/--config 没有对应环境变量,配置文件路径只能通过命令行传入。
  • 健康检查:镜像内置 HEALTHCHECK,每 30 秒用 busybox wget 探测公开端点 http://127.0.0.1:10100/ready(DB ping 通过时返回 200 与 {"status":"ready"},否则返回 503;wget 对非 2xx 退出非 0);用 docker inspect --format '{{.State.Health.Status}}' thurgio 查看状态,或在 docker run 时通过 --health-cmd 覆盖。

注意:默认监听 0.0.0.0:10100。请通过 -p 127.0.0.1:10100:10100 仅暴露到本机,并使用反向代理处理外部访问;不要在没有 TLS 的情况下将 Thurgio 直接暴露到互联网。

使用 Docker Compose 运行

# docker-compose.yml
services:
  thurgio:
    image: ghcr.io/xylylab/thurgio:latest   # 私有镜像;或本地构建的 thurgio:latest
    container_name: thurgio
    restart: unless-stopped
    ports:
      - "127.0.0.1:10100:10100"
    volumes:
      - ./config:/config:ro
      - thurgio-data:/data
    environment:
      - TZ=Asia/Shanghai
volumes:
  thurgio-data:

发布私有镜像

镜像发布到 GitHub Container Registry(GHCR)的私有包 ghcr.io/xylylab/thurgio,含 linux/amd64linux/arm64 两个架构(manifest list)。包默认私有——只有已登录且有访问权的账号能拉取;如要公开,去 GitHub 仓库的 Packages 页面把该包的可见性改为 public。

CI 自动发布.github/workflows/docker.yml):推送 v* 标签(即 just release 的 tag)时自动构建并推送 ghcr.io/xylylab/thurgio:vX.Y.Z:latest;手动触发(Actions 页面 Run workflow)推送 dev-<sha> 快照。

手动发布(无需 CI):

# 一次性登录(需要 write:packages scope;GitHub CLI 输出登录 token)
docker login ghcr.io --username <你的 GitHub 用户名>
gh auth token   # 输出到密码提示

# 构建并推送 amd64 + arm64
just docker-push tag=v0.18.0

# 覆盖默认 registry(如自建 registry:2):
THURGIO_REGISTRY=registry.example.com/thurgio just docker-push tag=v0.18.0

注意:镜像与 release 二进制一样是发布制品,构建后无法审计源码,请确保镜像与 tag 对应的 git 提交一致(CI 发布路径天然满足)。

自托管文档站点

docs/ 目录自带一份多阶段 Dockerfile:编译期安装最新 mdBook 构建本书(与 docs CI 工作流同一约定),运行期为 Caddy 静态站点(含 404 页与 gzip)。适合内网或离线环境查阅用户文档:

# 从仓库根目录构建(构建上下文即 docs/)
docker build -t thurgio-docs:latest docs/

docker run -d \
  --name thurgio-docs \
  -p 127.0.0.1:8080:80 \
  thurgio-docs:latest
# 打开 http://127.0.0.1:8080/

反向代理

始终将 Thurgio 运行在反向代理(nginx、Caddy)之后,以实现 TLS 终止、速率限制和访问控制。

Nginx

# /etc/nginx/sites-available/thurgio
upstream thurgio_backend {
    server 127.0.0.1:10100;
    keepalive 64;
}

server {
    listen 443 ssl http2;
    server_name thurgio.example.com;

    ssl_certificate     /etc/ssl/certs/thurgio.pem;
    ssl_certificate_key /etc/ssl/private/thurgio-key.pem;

    # 加固 TLS
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
    ssl_prefer_server_ciphers on;

    # 速率限制
    limit_req zone=thurgio:10m rate=30r/s;
    limit_req_status 429;

    # 代理所有请求到 Thurgio 后端
    location / {
        proxy_pass http://thurgio_backend;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_read_timeout 120s;
        proxy_send_timeout 120s;
    }

    # 可选:阻止对敏感端点的访问
    location /favicon.svg {
        proxy_pass http://thurgio_backend;
    }
    location /health {
        proxy_pass http://thurgio_backend;
    }
    location /metrics {
        # 将 metrics 限制为内部监控
        allow 10.0.0.0/8;
        allow 172.16.0.0/12;
        allow 192.168.0.0/16;
        deny all;
        proxy_pass http://thurgio_backend;
    }
}

Caddy

# Caddyfile
thurgio.example.com {
    reverse_proxy 127.0.0.1:10100
        health_uri /health
        health_interval 30s
    }

    # 可选:限制 metrics 端点
    @metrics {
        path /metrics
        not remote_ip 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16
    }
    handle @metrics {
        respond 403
    }

    rate_limit {
        zone dynamic {
            key {remote_host}
            events 30
            window 1s
        }
    }
}

Caddy 通过 Let’s Encrypt 自动配置 TLS 证书。


交叉编译

Thurgio 通过 cross 支持多平台交叉编译(见 justfile):

目标命令
Linux(musl,默认)just build-linuxx86_64-unknown-linux-musl
Windowsjust build-winx86_64-pc-windows-gnu
Androidjust build-androidaarch64-linux-android
Linux ARMjust build-arm-linuxaarch64-unknown-linux-musl

CI(.github/workflows/ci.yml)会在推送时构建 x86_64-unknown-linux-muslaarch64-linux-android 的 release 二进制并上传制品(含 SHA256)。


生产环境检查清单

上线前,请逐项确认:

安全

  • API 令牌 已从默认值改为强随机值,并按作用域分组: yaml setting: tokens: admin: - "admin-xyz789" # 管理操作(写、刷新、重载等) read: - "readonly-abc123" # 只读渲染
  • TLS 已启用——通过 Thurgio 内置 TLS 或反向代理。
  • 反向代理已配置——Thurgio 绑定到 127.0.0.1,而非 0.0.0.0
  • CORS 来源已限制——将 ["*"] 替换为具体域名: yaml setting: cors_origins: - "https://example.com"
  • 速率限制已启用——Thurgio 内置限流器(默认每 IP 每 60 秒 600 次,可用 THURGIO_RATE_LIMIT_REQUESTS / THURGIO_RATE_LIMIT_WINDOW_SECONDS 调整)、nginx 或 Caddy。

运维

  • systemd 单元 包含 Restart=always 和安全加固(使用 idle 模式时必须为 alwayson-failure 不会拉起正常退出)。
  • 服务日志 可通过 journalctl -u thurgio 查看(journald 自带轮转;仅当重定向到文件时才需要 logrotate)。
  • 输出目录已创建 且 Thurgio 用户可写入。
  • 模板目录 已填充且可读。
  • 数据库路径 已明确(DATABASE_URL,默认 thurgio.db),且所在目录可写。

监控

  • 健康端点 已监控(GET /health 返回版本、数据库状态、内存使用等)。
  • 就绪端点 用于负载均衡健康检查(GET /ready)。
  • 已通过 Prometheus 收集指标GET /metrics,包含请求指标、熔断器快照与渲染线程池指标)。
  • 缓存 TTL 配置合理yaml setting: ttl: provider: 600 # Provider 缓存有效期(秒,最小 60) snippet: 86400 # Snippet 缓存有效期(秒,最小 300)

性能

  • 并发限制已根据服务器调整yaml setting: concurrency_limit: 20 # 根据 CPU 核心数和网络情况调整(默认 10)
  • 渲染线程池参数已调整(如模板渲染量大):THURGIO_RENDERER_MIN_THREADS / THURGIO_RENDERER_MAX_THREADS
  • 反向代理中已启用 Keepalive(见上方 nginx/Caddy 配置)。

示例:完整生产环境布局

/usr/local/bin/
└── thurgio

/etc/
└── thurgio/
    ├── thurgio.yaml
    ├── provider.yaml
    ├── filter.yaml
    ├── rename.yaml
    ├── snippet.yaml
    └── tpls/
        ├── clash.tpl
        └── v2rayn.tpl

/var/
└── lib/
    └── thurgio/
        ├── output/              # 渲染的输出文件
        └── thurgio.db           # SQLite 数据库(自动创建)

/etc/systemd/system/
└── thurgio.service

/etc/nginx/sites-enabled/
└── thurgio.conf