Caddy:一行配置搞定自动 HTTPS 的反向代理

admin 开源软件 2026-10-23 7 0

反向代理解决三个问题:把多个服务收拢到 80/443、统一加 HTTPS、以及隔离内网服务与公网。

一、最常见的一套配置

example.com {
    encode gzip zstd
    reverse_proxy 127.0.0.1:8080
}

jellyfin.example.com {
    reverse_proxy 127.0.0.1:8096
}

api.example.com {
    reverse_proxy /v1/* 127.0.0.1:3000
    reverse_proxy 127.0.0.1:3001
}

就这么几行,它自动做完这些事:申请 Let's Encrypt 证书、配置自动续期、把 HTTP 请求 301 到 HTTPS、开启 HTTP/2、压缩响应。域名解析指向这台机器,证书当天就能下来。

二、它比传统方案省掉的四件事

  1. 证书申请与续期:不需要另装客户端、不需要定时任务;
  2. 跳转规则:不用手写 80 端口的 server 块;
  3. 配置语法:一个站点一个块,不需要记 location 匹配优先级;
  4. HTTP/3:UDP 443 放行后自动启用。

三、WebSocket 与长连接

很多自建服务(消息推送、终端、监控面板)依赖 WebSocket。传统方案要手动加 Upgrade 头,这在 Caddy 里是自动的——reverse_proxy 会透传升级请求。

但要配超时,否则长连接会被断:

reverse_proxy 127.0.0.1:8080 {
    transport http {
        read_timeout 1h
        write_timeout 1h
    }
}

四、几个容易踩的点

1. 证书申请失败

八成是这三个原因:域名没解析到本机、80 端口被占用或没放通、或者短时间内申请次数超限(Let's Encrypt 有频率限制)。先手动验证 curl -I http://域名/.well-known/acme-challenge/ 能不能通。

2. 大文件上传失败

默认没有请求体大小限制,但反代链路里如果还有别的组件(比如另一个代理、或者应用自身限制),就会出现「传到一半失败」。逐个排查:应用配置 → Caddy → 上游服务。

3. 真实 IP 丢失

后端拿到的都是 127.0.0.1,日志里没法看来源。需要让 Caddy 设置转发头,并让后端信任它:

reverse_proxy 127.0.0.1:8080 {
    header_up X-Real-IP {remote_host}
}

五、和内网服务的配合

安全上的正确姿势是:后端服务只监听 127.0.0.1,不映射到公网端口,所有外部访问都经过反向代理。

ports: ["127.0.0.1:8080:8080"]   # 只绑本地
# 而不是 ports: ["8080:8080"]     # 全网可达

这一条能挡掉大量自动扫描——扫描器只扫公网端口,不扫回环地址。

六、需要登录保护怎么办

它自带 basic auth,但对多服务场景不够用。更合适的做法是接一层统一认证,见 Authelia。

七、什么时候该选传统方案

如果你的场景有复杂的路径改写规则、需要大量 location 正则、或者要和现有 nginx 配置体系共存,那还是用传统方案。它的优势在「简单场景下省事」,不是「功能更全」。

关于自建服务的整体取舍,见 自建 vs SaaS;容器管理界面见 Dockge 与 Portainer。

相关阅读

评论

访问统计