强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

Caddy 从入门到精通 / 08 - API 与动态配置 / API & Dynamic Config

API 与动态配置 / API & Dynamic Config

Caddy 不仅有 Caddyfile 这种静态配置方式,还提供了一个完整的 REST API,可以在运行时动态管理配置。这是 Caddy 与 Nginx 最大的差异之一。

Beyond the static Caddyfile, Caddy provides a full REST API for dynamic runtime configuration. This is one of the biggest differences between Caddy and Nginx.


🟢 基础 / Basics

管理 API 端口

Caddy 默认在 localhost:2019 暴露管理 API:

# 查看当前运行状态
curl http://localhost:2019/

# 返回
{
    "status": "ok"
}

查看当前配置

curl http://localhost:2019/config/ | jq .

返回完整的 JSON 配置。

修改配置

# 用 POST 加载全新配置
curl -X POST http://localhost:2019/load \
    -H "Content-Type: application/json" \
    -d @config.json

重载配置(Caddyfile)

# 命令行方式
caddy reload --config /etc/caddy/Caddyfile

# 等价于自动执行了 adapt + API POST

🟡 进阶 / Intermediate

Caddyfile → JSON 转换

# 在终端查看转换后的 JSON
caddy adapt --pretty --config Caddyfile

# 保存到文件
caddy adapt --pretty --config Caddyfile > config.json

理解转换结果对调试非常有帮助。

API 路径结构

/config/                        # 完整配置
/config/apps/http/servers/      # HTTP 服务器配置
/config/apps/http/servers/myserver/routes/  # 路由列表
/config/apps/tls/               # TLS 配置

使用 PATCH 局部修改

不需要发送完整配置,只需修改局部:

# 添加一条路由
curl -X PATCH http://localhost:2019/config/apps/http/servers/myserver/routes/0 \
    -H "Content-Type: application/json" \
    -d '{
        "match": [{"host": ["new.example.com"]}],
        "handle": [{"handler": "static_response", "body": "New site"}]
    }'

使用 DELETE 删除路由

curl -X DELETE http://localhost:2019/config/apps/http/servers/myserver/routes/0

使用 GET 查看特定配置

# 查看所有路由
curl http://localhost:2019/config/apps/http/servers/myserver/routes/

# 查看第一条路由
curl http://localhost:2019/config/apps/http/servers/myserver/routes/0

配置热更新(Zero-Downtime)

API 修改配置时,Caddy 会:

  1. 验证新配置的合法性
  2. 应用新配置到内存
  3. 已建立的连接不受影响
  4. 新请求使用新配置

没有任何停机时间。

禁用管理 API

生产环境中,如果不需要动态配置:

{
    admin off
}

example.com {
    respond "Hello"
}

或限制监听地址:

{
    admin 127.0.0.1:2019
}

🔴 高级 / Advanced

API 驱动的多租户架构

#!/bin/bash
# add-tenant.sh — 通过 API 动态添加站点

DOMAIN=$1
BACKEND=$2

curl -X PATCH http://localhost:2019/config/apps/http/servers/myserver/routes/0 \
    -H "Content-Type: application/json" \
    -d "{
        \"match\": [{\"host\": [\"${DOMAIN}\"]}],
        \"handle\": [{
            \"handler\": \"reverse_proxy\",
            \"upstream\": [{\"dial\": \"${BACKEND}\"}]
        }],
        \"terminal\": true
    }"

echo "Added ${DOMAIN}${BACKEND}"

用法:

./add-tenant.sh tenant1.example.com localhost:3001
./add-tenant.sh tenant2.example.com localhost:3002

从文件系统加载子配置

Caddy 支持 JSON 配置中的 @id 引用:

{
    "apps": {
        "http": {
            "servers": {
                "myserver": {
                    "listen": [":443"],
                    "routes": [
                        {
                            "@id": "route-example",
                            "match": [{"host": ["example.com"]}],
                            "handle": [{"handler": "static_response", "body": "Hello"}]
                        }
                    ]
                }
            }
        }
    }
}

通过 API 单独操作带 @id 的部分:

curl http://localhost:2019/id/route-example
curl -X PATCH http://localhost:2019/id/route-example -d '...'

外部工具集成

用 Consul Template 动态生成配置

{{ service "web" }}
consul-template -template "Caddyfile.ctmpl:/etc/caddy/Caddyfile:caddy reload --config /etc/caddy/Caddyfile"

用 confd + etcd

confd -onetime -backend etcd -node http://127.0.0.1:2379
caddy reload

用自定义脚本监听变化

#!/bin/bash
# watch-and-reload.sh
inotifywait -m -e modify /etc/caddy/Caddyfile |
while read path action file; do
    caddy validate --config /etc/caddy/Caddyfile && \
    caddy reload --config /etc/caddy/Caddyfile
done

Graceful Restart 机制

旧进程收到 SIGHUP
    │
    ▼
启动新进程,继承 listener fd
    │
    ▼
新进程开始接受新连接
    │
    ▼
旧进程停止接受新连接
    │
    ▼
旧进程等待已有连接处理完毕
    │
    ▼
旧进程退出

Caddy 的 caddy reload 正是执行这个流程。

备份与恢复配置

# 导出当前运行配置
curl http://localhost:2019/config/ > backup-$(date +%Y%m%d).json

# 恢复
curl -X POST http://localhost:2019/load \
    -H "Content-Type: application/json" \
    -d @backup-20260510.json

API 安全

默认情况下管理 API 只监听 localhost。如果需要远程访问:

{
    admin 0.0.0.0:2019 {
        origins admin-ip.example.com
    }
}

结合 iptables 或网络策略限制访问:

iptables -A INPUT -p tcp --dport 2019 -s 管理员IP -j ACCEPT
iptables -A INPUT -p tcp --dport 2019 -j DROP

配置 Schema 验证

# 验证 Caddyfile 语法
caddy validate --config /etc/caddy/Caddyfile

# 验证 JSON 配置
caddy validate --config config.json --adapter json

Config Watcher(文件监听)

# Caddy 可以监听配置文件变化并自动重载
caddy run --watch --config /etc/caddy/Caddyfile

--watch 让 Caddy 监听 Caddyfile 变化,自动 reload。


小结 / Summary

层级内容
🟢 基础管理 API 端口、查看配置、caddy reload
🟡 进阶PATCH/DELETE/GET 局部修改、热更新、禁用 API
🔴 高级多租户 API 驱动、@id 引用、外部工具集成、API 安全、--watch

下一章:Docker 部署 / Docker Deployment