API 配置 #
概述 #
Caddy 提供了强大的管理 API,允许动态修改配置、管理证书、查看状态等,无需重启服务。
text
┌─────────────────────────────────────────────────────────────┐
│ Caddy API 架构 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ │
│ │ 客户端 │ │
│ └──────┬──────┘ │
│ │ HTTP 请求 │
│ ▼ │
│ ┌─────────────┐ │
│ │ 管理 API │ localhost:2019 │
│ │ 端口 2019 │ │
│ └──────┬──────┘ │
│ │ │
│ ▼ │
│ ┌─────────────┐ │
│ │ 配置存储 │ │
│ └─────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
API 端点 #
基本端点 #
| 端点 | 方法 | 说明 |
|---|---|---|
/config/ |
GET | 获取完整配置 |
/config/ |
POST | 设置完整配置 |
/load |
POST | 加载配置 |
/adapt |
POST | 转换配置格式 |
/stop |
POST | 停止服务器 |
/certificates |
GET | 获取证书列表 |
/pki/ca |
GET | 获取 CA 信息 |
/reverse_proxy/upstreams |
GET | 获取代理上游状态 |
配置管理 #
获取当前配置 #
bash
# 获取完整配置
curl localhost:2019/config/ | jq
# 获取特定部分
curl localhost:2019/config/apps/http | jq
# 获取服务器配置
curl localhost:2019/config/apps/http/servers | jq
加载配置 #
bash
# 加载 JSON 配置
curl -X POST \
-H "Content-Type: application/json" \
-d @caddy.json \
localhost:2019/load
# 加载 Caddyfile
curl -X POST \
-H "Content-Type: application/json" \
--data-binary '{"admin":"off"}' \
localhost:2019/load
更新部分配置 #
bash
# 使用 PATCH 更新部分配置
curl -X PATCH \
-H "Content-Type: application/json" \
-d '{"email": "new@example.com"}' \
localhost:2019/config/
# 更新特定路径
curl -X PATCH \
-H "Content-Type: application/json" \
-d '["example.com"]' \
localhost:2019/config/apps/http/servers/srv0/listen
删除配置 #
bash
# 删除特定配置
curl -X DELETE localhost:2019/config/apps/http/servers/srv0/routes/0
动态添加站点 #
添加新站点 #
bash
# 添加新站点配置
curl -X POST \
-H "Content-Type: application/json" \
-d '{
"match": [{
"host": ["new.example.com"]
}],
"handle": [{
"handler": "subroute",
"routes": [{
"handle": [{
"handler": "reverse_proxy",
"upstreams": [{
"dial": "localhost:4000"
}]
}]
}]
}],
"terminal": true
}' \
localhost:2019/config/apps/http/servers/srv0/routes
添加静态站点 #
bash
curl -X POST \
-H "Content-Type: application/json" \
-d '{
"match": [{
"host": ["static.example.com"]
}],
"handle": [{
"handler": "subroute",
"routes": [{
"handle": [{
"handler": "file_server",
"root": "/var/www/static"
}]
}]
}],
"terminal": true
}' \
localhost:2019/config/apps/http/servers/srv0/routes
反向代理管理 #
添加后端服务器 #
bash
# 添加新的后端
curl -X POST \
-H "Content-Type: application/json" \
-d '{"dial": "server4:3000"}' \
localhost:2019/config/apps/http/servers/srv0/routes/0/handle/0/routes/0/handle/0/upstreams
查看上游状态 #
bash
# 获取所有上游状态
curl localhost:2019/reverse_proxy/upstreams | jq
# 输出示例
{
"upstreams": [
{
"address": "localhost:3000",
"healthy": true,
"requests": 1234,
"fails": 2
},
{
"address": "localhost:3001",
"healthy": true,
"requests": 1180,
"fails": 1
}
]
}
移除后端服务器 #
bash
# 移除第一个后端
curl -X DELETE \
localhost:2019/config/apps/http/servers/srv0/routes/0/handle/0/routes/0/handle/0/upstreams/0
证书管理 #
查看证书 #
bash
# 获取所有证书
curl localhost:2019/certificates | jq
# 输出示例
{
"certificates": [
{
"domains": ["example.com", "www.example.com"],
"issuer": "Let's Encrypt",
"not_before": "2024-01-01T00:00:00Z",
"not_after": "2024-04-01T00:00:00Z"
}
]
}
手动获取证书 #
bash
# 通过配置触发证书获取
curl -X POST \
-H "Content-Type: application/json" \
-d '{
"email": "admin@example.com",
"domains": ["new.example.com"]
}' \
localhost:2019/certificates
配置导出 #
导出为 JSON #
bash
# 导出完整配置
curl localhost:2019/config/ > caddy-backup.json
# 导出特定部分
curl localhost:2019/config/apps/http > http-config.json
导出为 Caddyfile #
bash
# Caddyfile 转 JSON
caddy adapt --config Caddyfile --pretty > caddy.json
# JSON 转 Caddyfile(需要手动编写)
API 配置 #
启用/禁用 API #
caddyfile
{
# 启用 API(默认)
admin :2019
# 禁用 API
# admin off
# 只监听本地
admin localhost:2019
# 监听所有接口(不推荐)
# admin 0.0.0.0:2019
}
API 认证 #
caddyfile
{
admin {
# 使用基础认证保护 API
# 需要配置中间件
}
}
使用防火墙保护 API #
bash
# 只允许本地访问
sudo ufw allow from 127.0.0.1 to any port 2019
# 或使用 iptables
sudo iptables -A INPUT -p tcp --dport 2019 -s 127.0.0.1 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 2019 -j DROP
实用 API 示例 #
批量添加站点 #
bash
#!/bin/bash
# add-sites.sh
sites=(
"site1.example.com:3001"
"site2.example.com:3002"
"site3.example.com:3003"
)
for site in "${sites[@]}"; do
IFS=':' read -r domain port <<< "$site"
curl -X POST \
-H "Content-Type: application/json" \
-d "{
\"match\": [{\"host\": [\"$domain\"]}],
\"handle\": [{
\"handler\": \"subroute\",
\"routes\": [{
\"handle\": [{
\"handler\": \"reverse_proxy\",
\"upstreams\": [{\"dial\": \"localhost:$port\"}]
}]
}]
}],
\"terminal\": true
}" \
localhost:2019/config/apps/http/servers/srv0/routes
echo "Added $domain"
done
蓝绿部署切换 #
bash
#!/bin/bash
# blue-green-switch.sh
MODE=$1 # blue or green
if [ "$MODE" == "blue" ]; then
WEIGHTS='[{"dial": "blue-1:3000", "weight": 10}, {"dial": "blue-2:3000", "weight": 10}, {"dial": "green-1:3000", "weight": 0}, {"dial": "green-2:3000", "weight": 0}]'
elif [ "$MODE" == "green" ]; then
WEIGHTS='[{"dial": "blue-1:3000", "weight": 0}, {"dial": "blue-2:3000", "weight": 0}, {"dial": "green-1:3000", "weight": 10}, {"dial": "green-2:3000", "weight": 10}]'
else
echo "Usage: $0 blue|green"
exit 1
fi
curl -X PATCH \
-H "Content-Type: application/json" \
-d "$WEIGHTS" \
localhost:2019/config/apps/http/servers/srv0/routes/0/handle/0/routes/0/handle/0/upstreams
echo "Switched to $MODE environment"
金丝雀发布 #
bash
#!/bin/bash
# canary-release.sh
CANARY_WEIGHT=$1
STABLE_WEIGHT=$((100 - CANARY_WEIGHT))
curl -X PATCH \
-H "Content-Type: application/json" \
-d "[
{\"dial\": \"stable-1:3000\", \"weight\": $STABLE_WEIGHT},
{\"dial\": \"stable-2:3000\", \"weight\": $STABLE_WEIGHT},
{\"dial\": \"canary-1:3000\", \"weight\": $CANARY_WEIGHT},
{\"dial\": \"canary-2:3000\", \"weight\": $CANARY_WEIGHT}
]" \
localhost:2019/config/apps/http/servers/srv0/routes/0/handle/0/routes/0/handle/0/upstreams
echo "Canary weight set to $CANARY_WEIGHT%"
健康检查脚本 #
bash
#!/bin/bash
# health-check.sh
# 检查 API 是否响应
if curl -s localhost:2019/config/ > /dev/null; then
echo "API is healthy"
else
echo "API is not responding"
exit 1
fi
# 检查后端健康状态
UNHEALTHY=$(curl -s localhost:2019/reverse_proxy/upstreams | jq '[.upstreams[] | select(.healthy == false)] | length')
if [ "$UNHEALTHY" -gt 0 ]; then
echo "Warning: $UNHEALTHY unhealthy upstream(s)"
else
echo "All upstreams are healthy"
fi
配置持久化 #
自动保存配置 #
caddyfile
{
# 配置持久化
persist_config
}
手动保存配置 #
bash
# 导出当前配置
curl localhost:2019/config/ > /etc/caddy/caddy.json
# 使用 JSON 配置启动
caddy run --config /etc/caddy/caddy.json
API 安全 #
限制 API 访问 #
caddyfile
{
# 只监听本地
admin localhost:2019
# 或使用 Unix Socket
admin {
listen unix//var/run/caddy.sock
}
}
使用 TLS 保护 API #
caddyfile
{
admin {
# 使用 TLS
listen :2019
tls {
certificate /etc/ssl/caddy-api.crt
key /etc/ssl/caddy-api.key
}
}
}
API 访问日志 #
caddyfile
{
admin {
# 记录 API 访问
log {
output file /var/log/caddy/admin.log
}
}
}
完整示例 #
动态配置管理系统 #
bash
#!/bin/bash
# caddy-manager.sh
API="localhost:2019"
# 添加站点
add_site() {
local domain=$1
local backend=$2
curl -s -X POST \
-H "Content-Type: application/json" \
-d "{
\"match\": [{\"host\": [\"$domain\"]}],
\"handle\": [{
\"handler\": \"subroute\",
\"routes\": [{
\"handle\": [{
\"handler\": \"reverse_proxy\",
\"upstreams\": [{\"dial\": \"$backend\"}]
}]
}]
}],
\"terminal\": true
}" \
"$API/config/apps/http/servers/srv0/routes" > /dev/null
echo "Added site: $domain -> $backend"
}
# 删除站点
remove_site() {
local index=$1
curl -s -X DELETE \
"$API/config/apps/http/servers/srv0/routes/$index"
echo "Removed site at index $index"
}
# 列出站点
list_sites() {
curl -s "$API/config/apps/http/servers/srv0/routes" | \
jq -r '.[] | select(.match[0].host) | .match[0].host[0]'
}
# 查看状态
status() {
echo "=== Upstreams ==="
curl -s "$API/reverse_proxy/upstreams" | jq
echo -e "\n=== Certificates ==="
curl -s "$API/certificates" | jq
echo -e "\n=== Config ==="
curl -s "$API/config/apps/http/servers/srv0/routes" | jq 'length'
}
case "$1" in
add)
add_site "$2" "$3"
;;
remove)
remove_site "$2"
;;
list)
list_sites
;;
status)
status
;;
*)
echo "Usage: $0 {add|remove|list|status}"
;;
esac
下一步 #
现在你已经掌握了 API 配置,接下来学习 限流限速 了解如何保护你的服务!
最后更新:2026-03-28