[i=s] 本帖最后由 Hiccup 于 2025-1-23 11:23 编辑 [/i]<br />
<br />
Docker 部署 Caddy 反代教程
前言
Caddy 是一款功能强大且易于使用的 Web 服务器,以其自动 HTTPS 和简洁的配置而闻名。本教程将指导您如何使用 Docker 快速部署 Caddy 并将其配置为反向代理服务器。
之前曾经使用过Lucky和Traefik。
Lucky对于我来说,显得略微有些臃肿。好处是有webui,使用比较方便,功能也比较多,除了常规的自动申请证书,自动续订之外,还能DDNS,stun穿透等等。
Traefik的话,webui界面约等于没有,不过资源占用略低,http能自动跳转到https,也支持修改配置文件之后,自动重载。docker里面也支持标签自动发现等等功能。不过配置文件里面,域名和IP分成上下部分,修改起来不太方便。
下面是deepseek AI对于3款软件的对比
Nginx、Traefik 和 Caddy 简单对比
| 特性 | 
Nginx | 
Traefik | 
Caddy | 
| 定位 | 
高性能 Web 服务器/反向代理 | 
云原生反向代理和负载均衡器 | 
现代化、易用的 Web 服务器 | 
| 配置方式 | 
基于文件的配置(nginx.conf) | 
动态配置(支持多种后端) | 
基于文件的配置(Caddyfile) | 
| 自动 HTTPS | 
需要手动配置(如 Certbot) | 
内置支持(Let's Encrypt) | 
内置支持(Let's Encrypt) | 
| 易用性 | 
配置复杂,学习曲线较高 | 
中等,适合云原生环境 | 
非常简单,配置文件直观 | 
| 性能 | 
极高,适合高并发场景 | 
较高,适合动态环境 | 
较高,适合中小型应用 | 
| 扩展性 | 
通过模块扩展 | 
通过插件和中间件扩展 | 
通过插件扩展 | 
| 云原生支持 | 
需要手动集成 | 
原生支持 Kubernetes、Docker 等 | 
支持 Docker,Kubernetes 需插件 | 
| 社区生态 | 
非常成熟,文档丰富 | 
较新,但社区活跃 | 
较新,社区增长迅速 | 
| 适用场景 | 
高性能 Web 服务、静态文件服务 | 
云原生、微服务架构 | 
小型项目、快速部署、自动 HTTPS | 
| 配置文件示例 | 
nginx<br>server {<br> listen 80;<br> location / {<br> proxy_pass http://backend;<br> }<br>} | 
yaml<br>http:<br> routers:<br> my-router:<br> rule: "Host(example.com )"<br> service: my-service | 
Caddyfile<br>example.com {<br> reverse_proxy /api/* http://backend:8080<br>} | 
准备工作
- 域名 (既然反代了,你总得有个自己的域名吧?)
 
- 目标服务器 (都要反代了,总的有个反代的目标吧?)
 
步骤
1. 创建项目目录

在你喜欢的地方,创建一个caddy目录,并在目录下创建下一个data目录
2. 创建 Caddyfile.txt
Caddyfile 是 Caddy 的配置文件。
不过由于Caddy官方的docker镜像,并不支持由DNS验证来申请证书,
所以我们改用一个第三方的docker镜像,该镜像自动编译添加了官方的DNS验证申请证书的插件
镜像地址:sliamb/caddy
作者博客:caddy配置示例
镜像作者顺便修改了caddyfile为txt文件,更加方便飞牛编辑。
创建一个名为 caddyfile.txt 的文件并添加以下内容:
caddyfile.txt
{
    #修改docker全局监听端口
    http_port 8080  # 修改默认 HTTP 端口为 8080
    https_port 8443 # 修改默认 HTTPS 端口为 8443,外网访问的时候。就是域名:8443
}
# 泛域名配置
*.XXXXX.net {
    # 启用 TLS,使用 DNSPod 的 DNS-01 挑战申请泛域名证书
    tls {
        dns dnspod ID,TOKEN
    }
    #tls {
    #   dns alidns {
    #           access_key_id XXXXXXXXXXX
    #           access_key_secret XXXXXXXXXXXXX
    #           }
    #       }               alidns的格式未经测试,根据镜像作者文档修改而来,可能存在出错的可能,请各位自行尝试。
    #
    # 根据子域名配置反向代理,@AAA为服务名,保证上下一致即可,host后面则为外网访问域名,按需填写,proxy后面是内网ip,按需填写
    @AAA host AAA.XXXXX.XXX
    handle @AAA {
        reverse_proxy 10.10.10.2:5666
    }
    @BBB host BBB.XXXXX.XXX
    handle @BBBBB {
        reverse_proxy 10.10.10.1
    }
    @CCC host CCC.XXXXXX.XXX
    handle @CCC {
        reverse_proxy 10.10.10.3:8080
    }
    handle {
            respond 404#兜底规则,不匹配上面域名,则返回404
    }
}
说明:
3. 创建 docker-compose.yml
`

services:
  caddy:
    pull_policy: always
    image: sliamb/caddy:latest
    container_name: caddy
    restart: always
    environment:
      - TZ=Asia/Shanghai
      - DNS=223.5.5.5,8.8.8.8
    volumes:
      - /填写你刚才创建文件夹的路径:/data
    network_mode: "host"
说明:
使用host模式,性能会略好,但是可能会存在端口冲突问题,端口配置在caddyfile.txt的最开头,全局端口配置修改。
如果使用bridge模式,可以删除caddyfile.txt的全局端口配置,并映射80和443端口
4. 启动 Caddy
启动caddy,并在路由器开启转发caddy的https端口,也就是配置文件中的8443端口
5. 验证
- 访问 
http://aaa.example.com,请求将被代理到目标服务器。 
总结
通过以上步骤,您已经成功使用 Docker 部署了 Caddy 并将其配置为反向代理服务器。
您可以根据需要修改 caddyfile.txt 文件来配置更多功能,例如负载均衡、缓存等。
您也可以参考官网文档,来访问您自己的静态html,来为自己创建一个独一无二的导航页。
并且社区插件也支持ddns等各种功能,有能力的可以自行编译docker镜像。
该镜像的caddy,并不支持动态重载配置文件,所以每次修改完配置文件,需要重启才会生效。这算是其中一个略微影响我使用的缺点。
参考文档
B站-脑脑脑、Docker镜像作者博客、镜像作者Github项目页
更新内容:
1、由于飞牛远程访问需要证书,所以增加一个全局ddns的证书申请,并切换证书发行商为zerossl
2、caddy的自动http-https是针对于标准80端口-标准443端口的。但是对于大多数人的环境,并不适用。所以翻了几天的文档,在github找到了对应的解决方案。
3、增加某些本身就是https的网址反代。(其实就是跳过原本网址的证书验证)
再贴一次全部配置,我加上注释,按需修改。
{
    # 配置 DNSPod 的 DNS-01 挑战
    # email xxxxxx@qq.com  # 替换为您的邮箱
    # acme_dns cloudflare xxxxxxxxxxxxxxxxxxxxxxx  # 替换为 cloudflare 的 token
    # 以上两条是基于let‘s encrypt的格式,如果是zerossl,参考下面
    acme_ca https://acme.zerossl.com/v2/DV90       #切换证书发行商为ZeroSSL
    acme_eab {
        key_id  XXXXXXXXXXXXXXXXXX             #ZeroSSL网站上api的ID
        mac_key XXXXXXXXXXXX                   #ZeroSSL网站上api的KEY
    }
    auto_https disable_redirects                   #关闭caddy默认的自动https,因为它是基于标准端口的
    http_port 8080 # 修改默认 HTTP 端口为 8080
    https_port 8443 # 修改默认 HTTPS 端口为 8443
    servers {                                      #这一串代码块就是实现非标端口的http重定向https
        listener_wrappers {
            http_redirect
            tls
        }
    }
}
XXXXXX.com:8443 {                                   #增加一个主域名,不代理任何网站,只是为了申请一张证书,可以导出给其他设备使用
}
# 泛域名配置
*.xxxxxxxxx.com:8443 {
    # 根据子域名配置反向代理
    @fn host f.xxxxxxxxx.com
    handle @fn {
        reverse_proxy 10.10.10.2:5667 {
            transport http {                       #跳过本地的证书验证,由caddy加密
                tls_insecure_skip_verify
            }
        }
    }
    @ikuai host i.xxxxxxxxx.com                   #常用的反代
    handle @ikuai {
        reverse_proxy 10.10.10.1
    }
    handle {                                      #兜底规则,匹配不上以上任何网址,则返回404
        respond 404
    }
}
最后给一个证书导出的命令行。caddy的容器终端运行即可。
这个是ZeroSSL的证书位置,导出到caddyfile.txt的文件夹位置
cp -r ./.local/share/caddy/certificates/acme.zerossl.com-v2-dv90/ /data/cert/
如果是其他证书发行商。查询该路径,然后按需修改即可
ls ./.local/share/caddy/certificates/