同Docker Compose内Go服务访问Caddy的Mercure Hub出现SSL错误如何解决
问题根因确认
你的初始判断完全正确,该错误由Caddy侧SSL域名匹配失败触发:当前配置的SERVER_NAME参数仅为caddy域名开放了80端口HTTP访问,未对caddy域名配置443端口的SSL证书,因此TLS握手阶段Caddy找不到对应域名的证书配置,直接抛出内部错误。
你可以通过以下步骤验证根因:
- 进入caddy容器执行
caddy config list,检查443端口监听的主机名列表,确认是否包含caddy域名 - 在go_sse_listener容器中执行带
-k参数的curl命令临时关闭SSL校验:
若添加curl -k -v -L -N -H "Authorization: Bearer xxxxx" https://caddy/.well-known/mercure?topic=%2F.well-known%2Fmercure%2Fsubscriptions%7B%2Ftopic%7D%7B%2Fsubscriber%7D-k后可以正常拿到返回结果,即可确认根因为SSL域名匹配问题。
解决方案
你可以根据业务场景选择以下任意一种方案解决问题:
方案1:修改Caddy配置,开放内部域名SSL支持
直接修改docker-compose.prod.yml中caddy的SERVER_NAME环境变量,将caddy加入SSL域名列表:
caddy: environment: SERVER_NAME: ${SERVER_NAME:-localhost, caddy, caddy:80}
修改后重启Caddy服务,Caddy会自动为caddy域名签发自签SSL证书。如果你的Go服务不信任自签证书,可以做额外配置:
- 将Caddy容器内
/data/caddy/pki/authorities/local/root.crt文件挂载到go_sse_listener容器的/usr/local/share/ca-certificates/目录,容器启动时执行update-ca-certificates更新系统信任证书列表即可 - 开发环境下可临时关闭Go服务的SSL证书校验(不推荐生产环境使用)
方案2:内部通信走HTTP协议(推荐)
Docker内部网络本身是隔离的,不需要走SSL加密,直接将go_sse_listener的访问地址改为http://caddy/.well-known/mercure即可,你的现有配置已经开放了caddy:80的HTTP端口,无需额外修改配置,性能还优于HTTPS访问。
方案3:指定Host头复用公网域名配置
如果不想修改Caddy配置,访问时指定Host头为你的公网域名即可,Caddy会匹配到公网域名的SSL配置返回有效证书:
curl -v -L -N -H "Host: example.com" -H "Authorization: Bearer xxxxx" https://caddy/.well-known/mercure?topic=%2F.well-known%2Fmercure%2Fsubscriptions%7B%2Ftopic%7D%7B%2Fsubscriber%7D
对应Go代码中设置请求的Host字段为你的公网域名即可正常访问。
内容的提问来源于stack exchange,提问作者marioskamperis
相关产品推荐
相关产品推荐

