Caddy: 自动 HTTPS 的现代 Web 服务器¶
为什么要学 Caddy¶
配置 Nginx + Let's Encrypt SSL 证书是 Web 部署中最繁琐的环节之一:安装 certbot、配置定时续期、设置证书路径、处理证书过期报警……Caddy 把这一切变成了零配置。
| 维度 | Nginx | Caddy |
|---|---|---|
| HTTPS 配置 | 需要手动配置 certbot + 定时续期 | 全自动(申请/续期/部署) |
| 配置格式 | nginx.conf (复杂) | Caddyfile (简洁) 或 JSON API |
| 默认安全 | 需要手动加固 | 默认启用 HTTPS + 安全 Header |
| 反向代理 | 需要多行配置 | 一行搞定 |
| HTTP/2 | 需要配置 | 默认启用 |
| HTTP/3 | 需要额外编译 | 默认支持 |
| 热重载 | nginx -s reload | API 热重载 |
| 语言 | C | Go |
| 插件扩展 | 需要重新编译 | 模块化加载 |
Caddy 的核心价值观:服务器应该默认安全,HTTPS 不应该是可选的。
核心概念¶
白话解释¶
Caddy 是一个 Web 服务器,它自动做了三件传统需要手动配置的事情: 1. 自动 HTTPS:自动从 Let's Encrypt/ZeroSSL 申请证书,自动续期 2. 安全默认:HTTP 自动重定向到 HTTPS,启用现代 TLS 配置 3. 简单配置:一个域名 + 一个后端地址 = 完整的反向代理配置
核心概念表¶
| 概念 | 说明 | Nginx 等价物 |
|---|---|---|
| Caddyfile | 配置文件格式 | nginx.conf |
| Site Block | 一个站点的配置块 | server {} |
| Directive | 配置指令 | location / proxy_pass 等 |
| Automatic HTTPS | 自动证书管理 | certbot + cron |
| Reverse Proxy | 反向代理 | proxy_pass |
| File Server | 静态文件服务 | root + location |
| Matcher | 请求匹配器 | location 匹配 |
| Placeholder | 动态变量 | $variable |
| Admin API | 运行时管理 API | nginx -s reload |
Caddy vs Nginx 配置对比¶
反向代理示例:
# Nginx — 15+ 行
server {
listen 80;
server_name api.example.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
server_name api.example.com;
ssl_certificate /etc/letsencrypt/live/api.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem;
location / {
proxy_pass http://localhost:3000;
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;
}
}
Caddy 自动处理了:SSL 证书申请/续期、HTTP→HTTPS 重定向、安全 Header、HTTP/2。
安装配置¶
安装方式¶
macOS
Ubuntu/Debian
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install caddy
Arch Linux
Docker
docker run -d --name caddy \
-p 80:80 -p 443:443 \
-v caddy-data:/data \
-v caddy-config:/config \
-v $PWD/Caddyfile:/etc/caddy/Caddyfile \
caddy:latest
基本配置¶
创建 Caddyfile(默认位置 /etc/caddy/Caddyfile):
# 启动 Caddy
caddy run --config Caddyfile
# 后台运行
caddy start --config Caddyfile
# 停止
caddy stop
# 重载配置
caddy reload --config Caddyfile
# 使用 systemd(推荐生产环境)
sudo systemctl enable --now caddy
快速上手¶
静态文件服务¶
反向代理¶
# 单服务反向代理
api.example.com {
reverse_proxy localhost:3000
}
# 多服务反向代理(按路径分发)
example.com {
reverse_proxy /api/* localhost:3000
reverse_proxy /ws/* localhost:3001
root * /var/www/frontend
file_server
}
多站点配置¶
# 多个域名,一个 Caddyfile
app.example.com {
reverse_proxy localhost:3000
}
api.example.com {
reverse_proxy localhost:8080
}
docs.example.com {
root * /var/www/docs
file_server
}
# 通配符域名
*.example.com {
tls {
dns cloudflare {env.CF_API_TOKEN}
}
reverse_proxy localhost:9000
}
本地开发(HTTP)¶
# 开发环境不需要 HTTPS
:8080 {
reverse_proxy localhost:3000
}
# 或者使用 localhost(Caddy 会生成自签名证书)
localhost {
reverse_proxy localhost:3000
}
进阶用法¶
负载均衡¶
example.com {
reverse_proxy localhost:3001 localhost:3002 localhost:3003 {
# 负载均衡策略
lb_policy round_robin
# 其他策略: random, first, least_conn, ip_hash
# 健康检查
health_uri /health
health_interval 10s
health_timeout 5s
health_status 200
# 失败重试
lb_try_duration 5s
lb_try_interval 250ms
}
}
Header 管理¶
example.com {
reverse_proxy localhost:3000
# 添加安全 Header
header {
X-Content-Type-Options "nosniff"
X-Frame-Options "DENY"
Referrer-Policy "strict-origin-when-cross-origin"
Strict-Transport-Security "max-age=31536000; includeSubDomains"
Content-Security-Policy "default-src 'self'"
-Server # 删除 Server header
}
}
CORS 配置¶
api.example.com {
reverse_proxy localhost:3000
@cors_options method OPTIONS
handle @cors_options {
header Access-Control-Allow-Origin "*"
header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"
header Access-Control-Allow-Headers "Content-Type, Authorization"
header Access-Control-Max-Age "86400"
respond "" 204
}
header Access-Control-Allow-Origin "*"
}
请求限流¶
example.com {
rate_limit {
zone dynamic_zone {
key {remote_host}
events 100
window 1m
}
}
reverse_proxy localhost:3000
}
基本认证¶
admin.example.com {
basicauth {
# 密码用 caddy hash-password 生成
admin $2a$14$...hashed_password...
}
reverse_proxy localhost:9090
}
日志配置¶
example.com {
log {
output file /var/log/caddy/access.log {
roll_size 100mb
roll_keep 10
roll_keep_for 720h
}
format json
level INFO
}
reverse_proxy localhost:3000
}
WebSocket 代理¶
# WebSocket 自动支持,无需额外配置
example.com {
reverse_proxy /ws localhost:3001
reverse_proxy localhost:3000
}
压缩¶
Docker Compose 完整示例¶
version: '3'
services:
caddy:
image: caddy:latest
ports:
- '80:80'
- '443:443'
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
- caddy-data:/data
- caddy-config:/config
restart: unless-stopped
app:
image: my-app:latest
expose:
- '3000'
api:
image: my-api:latest
expose:
- '8080'
volumes:
caddy-data:
caddy-config:
Admin API¶
# Caddy 提供 REST API 进行运行时管理
# 获取当前配置
curl localhost:2019/config/
# 更新配置(不重启)
curl localhost:2019/load \
-H "Content-Type: text/caddyfile" \
--data-binary @Caddyfile
# 添加新路由
curl -X POST localhost:2019/config/apps/http/servers/srv0/routes \
-H "Content-Type: application/json" \
-d '...'
常见问题¶
Q1: Caddy 的自动 HTTPS 如何工作?¶
- Caddy 检测到配置中的域名
- 自动向 Let's Encrypt(或 ZeroSSL)申请证书
- 通过 HTTP-01 或 TLS-ALPN-01 验证域名所有权
- 下载并安装证书
- 在证书到期前自动续期
前提:域名的 DNS 指向 Caddy 服务器,且 80/443 端口可访问。
Q2: 内网服务怎么用 Caddy?¶
内网服务器没有公网访问,不能用 Let's Encrypt。选择: - 使用 localhost 或 IP(Caddy 生成自签名证书) - 使用内部 CA 签发证书 - DNS 验证方式(需要 Caddy DNS 插件)
Q3: Caddy 性能和 Nginx 比怎么样?¶
- 静态文件服务:Nginx 略快(C vs Go)
- 反向代理:几乎无差异
- 实际场景中,瓶颈几乎不在 Web 服务器层
- Caddy 的优势是运维成本低(自动 HTTPS、简单配置)
Q4: 如何从 Nginx 迁移?¶
Caddy 没有自动迁移工具,但配置转换通常很简单: - server {} → 域名块 example.com {} - proxy_pass → reverse_proxy - root + location → root * path + file_server - SSL 配置全删(Caddy 自动处理)
Q5: 如何使用通配符证书?¶
需要 DNS 验证,安装对应的 DNS Provider 插件:
参考资源¶
| 资源 | 链接 |
|---|---|
| 官方网站 | https://caddyserver.com |
| GitHub 仓库 | https://github.com/caddyserver/caddy |
| Caddyfile 文档 | https://caddyserver.com/docs/caddyfile |
| 指令参考 | https://caddyserver.com/docs/caddyfile/directives |
| JSON API 文档 | https://caddyserver.com/docs/json |
| 社区插件 | https://caddyserver.com/download |
| xcaddy(自定义构建) | https://github.com/caddyserver/xcaddy |
总结:Caddy 是 Web 服务器领域"配置即安全"理念的代表。如果你厌倦了配置 Nginx SSL 证书的繁琐流程,Caddy 的自动 HTTPS 就是你需要的。对于中小型项目和个人部署,Caddy 的简洁配置和默认安全让部署变成了一件轻松的事。