Docker Swarm下Nginx容器Let's Encrypt证书仅默认端口生效问题
问题成因
- HSTS策略拦截
你之前访问过test环境的https://example.com,该站点返回的HSTS响应头会让浏览器强制对example.com域名的所有请求走HTTPS,且浏览器的HSTS实现默认仅信任443端口的合法证书,访问非443端口的8443时,哪怕使用相同的合法证书,也会直接触发拦截,不提供跳过选项,直接返回HSTS相关错误。而IP地址不受HSTS策略绑定,因此访问IP加端口时仅出现普通证书不匹配警告(证书颁发给域名而非IP),允许跳过访问。 - 证书加载异常(可选验证项)
如果共享存储卷的挂载权限配置错误,dev环境的Nginx容器无权限读取Certbot生成的证书文件,会默认加载自带的自签名证书,触发证书无效报错。你可以通过以下命令校验返回的证书是否合法:openssl s_client -connect example.com:8443 -servername example.com
如果返回的证书颁发者不是Let's Encrypt,就是加载异常导致的。
解决方案
长期规范方案(推荐)
- 为dev环境分配独立二级域名,比如
dev.example.com,解析到当前服务器IP - 重新申请Certbot证书,将
dev.example.com加入证书的SAN扩展列表,新证书仍存储在共享卷供两个环境使用 - 调整test环境的Nginx配置作为统一入口,不用暴露dev环境的8443、8080端口:新增server块匹配
dev.example.com的请求,直接转发到dev栈的Nginx服务即可,两套环境都通过443端口访问,完全规避HSTS和端口问题。
临时调试方案
如果仅用于内部调试,不需要对外提供服务:
- 先清理浏览器中
example.com的HSTS缓存:以Chrome为例,访问chrome://net-internals/#hsts,在「Delete domain security policies」输入框填入example.com,点击删除后重启浏览器 - 如果是证书加载异常导致的问题,调整共享卷的挂载权限,保证dev环境的Nginx容器对证书目录有可读权限,重启dev的Nginx服务即可
- 也可以直接使用IP加端口的方式访问,忽略证书警告后正常使用
内容的提问来源于stack exchange,提问作者Pepsko
相关产品推荐
相关产品推荐

