Caddy 最佳实践与演进史 caddy Caddy Reverse Proxy TLS 杂项
2114 字
11 分钟
Caddy 最佳实践与演进史

从历史看 Caddy 的野心#

  • 2015 年:Matt Holt 发布 Caddy 1.0 Beta,定位“自动 HTTPS 的现代 Web 服务器”。彼时主流仍是 Nginx/Apache 人工申领证书,Caddy 首次将 Let’s Encrypt ACME 流程写入默认行为,HTTP/2 默认开启。
  • 2016 年:引入 Caddyfile 配置语法,被称为“Go 版 Nginx”。社区围绕插件(proxy, markdown, git 等)快速扩展。
  • 2017 年:Caddy 0.10 起将多租户、TLS On-Demand、自动 HTTP->HTTPS 重定向等能力放入核心。官方尝试商业化授权,引发争议后在 2018 年改为 Apache-2.0 + 商业增值模式(Certified Caddy)。
  • 2020 年:Caddy 2 GA,底层完全重写为模块化框架(多称“xcaddy 生态”),引入 Admin API、JSON 配置、无锁热加载。官方成立 Light Code Labs,提供企业支持。
  • 2022 年以后:默认支持 HTTP/3、自动 OCSP Stapling、Zero-downtime Reload;与 Kubernetes、Docker、Nomad、Consul 等集成插件生态完善。

对比 Nginx 从“高性能 Web 服务器”进化而来,Caddy 一开始便围绕“安全默认值、自动化”设计,目标是成为现代分发层的“操作系统”。

为什么在 2025 年仍然推荐 Caddy#

  1. 自动 HTTPS & TLS 生命周期托管:证书申请、续期、失效检测、OCSP Stapling 全自动。对多域名、Wildcard、On-Demand TLS(多租户 SaaS)极其友好。
  2. 默认安全:HTTP/2/HTTP/3、Strict-Transport-Security、自动重定向、合理的 Cipher Suite 默认值,大幅降低安全配置错误的风险。
  3. 配置友好Caddyfile 上手快,caddy fmt 保持一致性;热加载无需重启。需要时可转换为 JSON,通过 Admin API 动态修改,适合“声明式 + 程序化”双模式。
  4. 模块化架构:任何功能(服务器、路由、TLS、日志、存储、认证)都是插件,可用 xcaddy 定制镜像。灵活程度远超 Nginx/Envoy 传统模块。
  5. Go 实现,资源占用轻:二进制单文件,无外部依赖,容器镜像可做到 < 50MB。相比 Java 生态(如 Spring Gateway)启动速度快几倍。
  6. 原生 HTTP/3 & QUIC:不依赖 OpenSSL,直接使用 Go 标准库 QUIC 实现;对移动端、弱网场景优化明显。
  7. 强大的反向代理能力:支持请求匹配(主机、路径、Header、Query)、重写、负载均衡、熔断、健康检查、缓存、CORS、速率限制。
  8. 企业级扩展:商业版提供集中式证书管理、SAML/LDAP 认证、Metrics/Tracing 集成;社区版亦支持 OpenTelemetry、Prometheus。

核心架构解剖#

Caddy (Process)
├── Admin API (REST/Unix Socket)
├── Modules (caddyserver.com/docs/modules/)
│ ├── HTTP Server (caddyhttp)
│ │ ├── Routes, Matchers, Handlers
│ │ └── Reverse Proxy (caddyhttp/reverseproxy)
│ ├── TLS (caddytls)
│ ├── Logging (caddy.logging)
│ ├── Storage (certificate store: file system, Consul, etcd…)
│ └── Apps (HTTP、TLS、PKI、DNS 等)
└── Config Manager
├── Caddyfile
├── JSON (REST PUT/POST)
└── Autoload (watch config changes)
  • 模块化设计:Caddy 2 一切皆模块,HTTP Server 是 apps.http 模块之一。加载配置后通过 dependency graph 构建 pipeline。
  • Admin API:默认监听 :2019(或 Unix socket),支持 POST /load, POST /config/apps/http/servers/srv0/routes 动态更新。
  • 证书存储:默认 ~/.local/share/caddy, 可切换为 S3、Consul、Redis 等远程存储,使多副本共享证书。
  • 热重载:变更配置时先启动新实例,通过引用计数停掉旧实例,无需中断现有连接。

快速上手:安装与基础配置#

安装方式#

Terminal window
# Linux 官方脚本(含 systemd 服务)
curl -sfL https://get.caddyserver.com | bash -s personal
# Homebrew
brew install caddy
# Docker
docker run -p 80:80 -p 443:443 \
-v $PWD/Caddyfile:/etc/caddy/Caddyfile \
caddy:2-alpine
# 自定义模块
xcaddy build v2.8.4 \
--with github.com/caddy-dns/cloudflare \
--with github.com/mholt/caddy-dynamicdns

Ubuntu 环境部署示例#

官方推荐通过 Cloudsmith 仓库安装,以便跟随稳定版更新:

Terminal window
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo tee /usr/share/keyrings/caddy-stable-archive-keyring.gpg > /dev/null
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

安装完成后,Caddy 以 caddy 系统用户运行并注册为 systemd 服务:

Terminal window
sudo systemctl status caddy
sudo systemctl enable --now caddy

反向代理 Node.js(端口 3000)示例:

  1. 编辑 /etc/caddy/Caddyfile

    example.com {
    reverse_proxy 127.0.0.1:3000
    encode zstd gzip
    header {
    Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
    }
    }
  2. 确认 DNS A/AAAA 记录指向服务器,放行 80/443 端口(如使用 UFW:sudo ufw allow 80,443/tcp)。

  3. 使用内置格式化与配置校验:

    Terminal window
    sudo caddy fmt --overwrite /etc/caddy/Caddyfile
    sudo caddy validate --config /etc/caddy/Caddyfile
  4. 热重载并查看日志:

    Terminal window
    sudo systemctl reload caddy
    journalctl -u caddy -f

首次访问 https://example.com 即可看到自动颁发的 Let’s Encrypt 证书,后续续期与 OCSP 由 Caddy 自行处理。若需要自定义证书目录,可在 /etc/caddy/Caddyfile 顶部使用全局段 storage file_system { root /var/lib/caddy } 或挂载远程存储。

Hello Reverse Proxy#

Caddyfile:

example.com {
reverse_proxy 127.0.0.1:3000
}

执行:

Terminal window
caddy run --config Caddyfile --watch

打开浏览器访问 https://example.com 即自动申请证书并转发请求。

进阶配置精要#

多域名站点 + 自动重定向#

{
email admin@example.com
auto_https disable_redirects # 自定义重定向
}
example.com, www.example.com {
@httpScheme protocol http
handle @httpScheme {
redir https://{host}{uri} permanent
}
encode zstd gzip
reverse_proxy {
to app1:8080 app2:8080
lb_policy least_conn
health_interval 20s
health_timeout 5s
}
log {
output file /var/log/caddy/example.log {
roll_size 20MB
roll_keep 7
}
format json
}
}

动态配置(Admin API)#

Terminal window
curl -X POST http://localhost:2019/load -H "Content-Type: application/json" -d @config.json

配置片段(JSON):

{
"apps": {
"http": {
"servers": {
"srv0": {
"listen": [":443"],
"routes": [
{
"match": [{ "host": ["api.example.com"] }],
"handle": [
{
"handler": "reverse_proxy",
"upstreams": [{ "dial": "api:9000" }]
}
]
}
]
}
}
}
}
}

TLS 自动化选项#

*.tenant.example.com {
tls {
on_demand # 客户首次访问时动态申请证书
issuer acme {
email tls@example.com
dns cloudflare {env.CLOUDFLARE_API_TOKEN}
}
renew_before 720h # 提前 30 天续期
}
reverse_proxy {host}.backend.internal:8443
}

On-Demand TLS 需配合访问控制(例如 tls.on_demand ask https://tenant-registry/api/check)避免被恶意滥用。

HTTP/3 与 QUIC 调优#

  • 默认开启 HTTP/3;如需关闭:auto_https disable_certs + servers { protocols { enable h3 disable h1 h2 } }
  • 对移动端可增加 header Response add Alt-Svc "h3=\":443\"; ma=86400"

缓存与边缘处理#

https://assets.example.com {
root * /var/www/assets
file_server
header {
Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
Cache-Control "public, max-age=31536000, immutable"
}
handle_path /api/* {
reverse_proxy backend:8080
header_up X-Forwarded-Proto {scheme}
header_up X-Request-Id {http.request.id}
}
}

与 Nginx / Traefik / Envoy 的对比#

特性CaddyNginxTraefikEnvoy
自动 HTTPS✅ 默认❌ 需 Certbot✅ Provider❌ 外部实现
配置体验Caddyfile/JSON/RESTnginx.confTOML/YAML/CRDYAML/ADS
动态配置Admin API需 reloadProvider/动态发现xDS
HTTP/3 支持内建稳定实验 (依赖 quic patch)实验
模块扩展Go 模块 xcaddy编译模块插件自定义 Filter
性能优秀 (Go, 多核友好)极佳 (C 基础)极佳 (C++)
学习曲线
适用场景Web 前端、SaaS、多租户老牌反向代理云原生 ingress微服务服务网格

Caddy 不追求取代所有场景,但在希望“快速上线、安全默认、自动化证书”的团队中胜率很高。

生产实践建议#

  • 版本管理:固定到 caddy:2.x.y,关注 Release Notes
  • 配置托管:将 Caddyfile 与 JSON 配置放入 Git,使用 caddy fmt + Pre-commit 保持规范。
  • 日志与监控
    • log { format json } 便于 ELK/ClickHouse 分析。
    • 启用 metrics 模块,或集成 Prometheus Exporter。
    • 利用 admin metrics 暴露运行指标。
  • 证书持久化:在容器部署时挂载 /data,或使用远程存储模块避免容器重建导致重新申请证书。
  • 安全
    • 限制 Admin API 仅监听 Unix socket 或内网地址。
    • 对 on-demand TLS 设置 ask 校验接口。
    • 加固 auto_https disable_redirects 场景中的手动重定向链,防止开放端口被利用。
  • 高可用:多实例部署时共享证书存储,或通过 caddy.cluster.consul 模块同步状态。
  • 性能调优
    • 合理设置 reverse_proxymax_requestsmax_conns
    • 在高并发场景打开 buffers 和响应压缩。
    • 使用 layer4 模块处理 TCP/UDP(数据库代理)。

典型落地场景#

  1. 个人/团队博客:一套 Caddyfile 管理多个站点,Let’s Encrypt 自动续期免维护。
  2. SaaS 多租户域名:On-Demand TLS + DNS Provider 模块 + 动态 upstream。
  3. 微服务网关:配合 Consul/Etcd 服务发现模块、JWT 验证、速率限制。
  4. 静态资源/CDN 边缘节点:结合 Rclone/S3 同步,利用 HTTP/3 提升移动端体验。
  5. DevOps 内部工具:通过 trusted_proxies、Basic Auth/OAuth 插件保护内部管理端。

学习路线与工具#

  • caddy helpcaddy list-modules:快速了解已安装模块。
  • caddy fmt:格式化 Caddyfile。
  • caddy adapt --config Caddyfile --adapter caddyfile --pretty:将 Caddyfile 转换为 JSON,便于自动化。
  • xcaddy 构建带自定义模块的二进制。
  • 官方文档 + Caddy Community Forum
  • 深入阅读 Matt Holt 的博客与演讲,如 “Caddy 2: The Ultimate Modern Web Server”。

结语#

十年间,Caddy 从“自动 HTTPS 小众服务器”成长为成熟的边缘分发平台。它在默认安全、配置体验、动态化方面的设计理念,与现代应用架构的诉求高度契合。对追求“少折腾、快上线、易维护”的团队而言,Caddy 不只是 Nginx 的替代品,更是一次重新思考反向代理和 TLS 生命周期管理的机会。

掌握本文提到的历史视角、优势与实战经验,你可以更有底气地在项目中引入 Caddy,并构建稳定可靠的应用交付层。

Caddy 最佳实践与演进史
https://bangwu.top/posts/caddy/
作者
棒无
发布于
2025-11-05
许可协议
CC BY-NC-SA 4.0