反向代理选型:Nginx、Caddy、Traefik 实际用下来的差别

自建服务 · 7 分钟阅读· 6 次阅读

家里那台小主机上跑着 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。

理由:

  1. 证书零配置,这是最大的时间节省
  2. 配置文件短,改起来不容易错
  3. 家用的服务数量固定,不需要 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)

还没有评论,来说两句吧~

发表评论

验证码

提交后需站长审核,通过后才会显示。