反向代理选型:Nginx、Caddy、Traefik 实际用下来的差别
家里那台小主机上跑着 9 个 Web 服务,全都要 HTTPS。这三年我把 Nginx、Caddy、Traefik 各跑过一段时间,记录一下实际差别。
一、证书:Caddy 完胜
Caddy:
example.com {
reverse_proxy localhost:3000
}
两行,自动申请 Let's Encrypt 证书、自动续期、自动 HTTP→HTTPS 跳转。不需要装 certbot,不需要写 cron。
Nginx:要装 certbot,配置要写 4 个 server 块(80 跳转、443、SSL 参数、location),续期靠 systemd timer,还要写 postrotate 让 nginx reload。
Traefik:也自动,但要在 compose 里写一堆 labels:
labels:
- "traefik.enable=true"
- "traefik.http.routers.app.rule=Host(`app.example.com`)"
- "traefik.http.routers.app.tls.certresolver=le"
证书这块,Caddy 是唯一做到「零配置」的。
二、配置可读性
Nginx 的配置最啰嗦,但最多人懂:
server {
listen 443 ssl http2;
server_name app.example.com;
ssl_certificate /etc/letsencrypt/live/app/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/app/privkey.pem;
location / {
proxy_pass http://127.0.0.1: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;
}
}
那一堆 proxy_set_header 是 Nginx 的经典坑:不写的话后端拿到的客户端 IP 全是 127.0.0.1,Host 头也不对,很多框架的路由会出错。
Caddy 同样的功能:
app.example.com {
reverse_proxy localhost:3000
}
Host、X-Forwarded-* 全部自动处理。
Traefik 的配置在 labels 里,可读性最差,但好处是跟容器生命周期绑定——容器起来自动注册,起来就生效。
三、动态服务发现:Traefik 的核心优势
如果你经常增删容器,Traefik 是最省心的:新容器打上 labels,自动上线,不用碰代理配置。
Caddy 也可以做动态上游,但需要 Caddyfile 里写 reverse_proxy 指向 Docker 服务名(同一网络里),或者用 admin API。
Nginx 最死板:加一个服务就要改配置文件 reload。这在家庭场景(一个月加不了一个服务)问题不大,但在频繁部署的环境里很烦。
四、性能
都是反代,性能差别在家庭场景下可以忽略。实测(N100,本地回环,wrk 压测静态文件):
| 代理 | Requests/sec | 延迟 p99 |
|---|---|---|
| Nginx | 28,400 | 3.2ms |
| Caddy | 24,100 | 4.1ms |
| Traefik | 21,800 | 5.6ms |
Nginx 最快,但都是万级,家用根本跑不到。这一项不构成选择理由。
五、排障体验
Nginx:日志分 access/error,error.log 很详细,社区答案多。出问题搜一下基本都能找到。
Caddy:日志是 JSON 格式,需要 jq 过滤。默认日志不够详细时要手动开 debug。但配置少,出错的地方也少。
Traefik:出问题时最难查。labels 写错一个字符,路由就不生效,而且日志里只说「no router found」,不会告诉你哪个 label 写错了。我在这上面浪费过一个晚上。
六、我最后的选择
Caddy。
理由:
- 证书零配置,这是最大的时间节省
- 配置文件短,改起来不容易错
- 家用的服务数量固定,不需要 Traefik 的动态发现
代价:
- 社区资料比 Nginx 少(但官方文档很好)
- 一些高级功能(复杂的 rewrite、限流)不如 Nginx 灵活
一份我实际在用的 Caddyfile
{
email me@example.com
# 本地服务的上游
}
# 主站
blog.example.com {
encode zstd gzip
root * /var/www/blog
file_server
php_fastcgi unix//run/php/php8.3-fpm.sock
header {
Strict-Transport-Security "max-age=31536000; includeSubDomains"
X-Content-Type-Options nosniff
Referrer-Policy strict-origin-when-cross-origin
}
log {
output file /var/log/caddy/blog.log {
roll_size 10mb
roll_keep 3
}
}
}
# 自建服务
vault.example.com {
reverse_proxy localhost:8081
}
git.example.com {
reverse_proxy localhost:3000
}
# 只在内网访问的服务
nas.example.com {
@notlocal not remote_ip 192.168.10.0/24
respond @notlocal "Forbidden" 403
reverse_proxy 192.168.10.20:5000
}
最后那段 @notlocal 很有用:Caddy 支持按来源 IP 拒绝,不用在防火墙上折腾。
什么情况选什么
- 只要几个站、要省心:Caddy
- 团队里都熟 Nginx、要复杂规则:Nginx
- 容器频繁增删、要自动发现:Traefik
- 要做 API 网关、灰度发布:Traefik 或 Envoy
家庭自建,我的建议是先上 Caddy。等哪天被它的某个限制卡住了,再换也不迟——迁移成本不高,因为后端服务的配置不用改。
评论 (0)
还没有评论,来说两句吧~
发表评论