Docker环境下通过Nginx反向代理SSL连接Azure MySQL弹性服务器超时问题求助
Docker环境下通过Nginx反向代理SSL连接Azure MySQL弹性服务器超时问题求助
兄弟,我之前折腾过类似的场景,咱们一步步来排查和解决这个问题哈!
首先,你的思路完全没问题:让Nginx作为TCP代理,替Web2Py应用处理和Azure MySQL的SSL加密连接,既避开了应用不支持SSL的短板,又能满足Azure强制开启require_secure_transport的要求。现在请求超时大概率是Nginx的代理配置没到位,或者存在网络/权限层面的问题,咱们逐个排查:
一、先补上Nginx的MySQL TCP代理配置(核心!)
MySQL是基于TCP的协议,没法用Nginx的HTTP代理规则,得用stream模块来做正向代理。你当前的Nginx配置里应该还没加这块,这是最可能的超时原因。
1. 准备Azure MySQL的根证书
Azure MySQL依赖DigiCert的根证书做SSL验证,先把证书下载到本地:
wget https://cacerts.digicert.com/DigiCertGlobalRootCA.crt.pem -P ./nginx/ssl/
然后在docker-compose的nginx服务里添加证书挂载:
volumes: # 保留你原来的挂载项... - ./nginx/ssl/DigiCertGlobalRootCA.crt.pem:/etc/nginx/ssl/DigiCertGlobalRootCA.crt.pem:ro
2. 添加Stream代理配置
在Nginx的配置目录(比如./nginx/conf.d/)新建stream.conf文件,内容如下:
stream { server { # 监听容器内的3306端口,供Web2Py连接 listen 3306; # 转发到你的Azure MySQL服务器地址和端口(Azure默认是3306) proxy_pass your-azure-mysql-host.mysql.database.azure.com:3306; # 开启SSL代理,和Azure MySQL建立加密连接 proxy_ssl on; # 指定信任的根证书路径 proxy_ssl_trusted_certificate /etc/nginx/ssl/DigiCertGlobalRootCA.crt.pem; # 开启SSL证书验证 proxy_ssl_verify on; proxy_ssl_verify_depth 2; # 调整超时参数,避免连接过早断开 proxy_connect_timeout 15s; proxy_timeout 60s; } }
接着修改Nginx的主配置nginx.conf(如果用默认配置,可挂载自定义的nginx.conf,或者在默认文件里添加),确保加载这个stream配置:
# 在http块的外部添加 include /etc/nginx/conf.d/stream.conf;
二、检查Docker网络与端口连通性
- 确认网络互通:你的docker-compose已经把两个服务都加入
web2py网络,Web2Py通过nginx:3306访问是没问题的。 - 测试Web2Py到Nginx的连通性:
先进入Web2Py容器:
用telnet测试端口:docker exec -it <web2py容器名> sh
如果能连通,说明网络没问题;如果连不上,检查Nginx是否正确监听3306端口(进入Nginx容器执行telnet nginx 3306netstat -tulpn | grep 3306),或者用nginx -t检查配置语法是否有误。
三、验证Nginx到Azure MySQL的连通性
进入Nginx容器,直接测试连接Azure MySQL:
docker exec -it <nginx容器名> sh # Alpine镜像先安装mysql客户端 apk add mysql-client # 替换成你的Azure MySQL信息测试连接 mysql -h your-azure-mysql-host.mysql.database.azure.com -u 你的用户名@你的服务器名 -p --ssl-mode=REQUIRED
如果连接失败,大概率是Azure MySQL的防火墙没放行Nginx容器的出口IP(也就是宿主机的公网IP),去Azure门户的MySQL服务器防火墙规则里添加宿主机IP即可。
四、其他容易踩的坑
- Azure MySQL的用户名格式必须是
用户名@服务器名,别只写单纯的用户名,否则会认证失败。 - 确认Nginx的stream模块可用:官方
nginx:alpine镜像默认包含stream模块,如果是自定义镜像,要确保编译时加了--with-stream参数。
按照这些步骤走一遍,应该能解决超时问题,有问题随时喊我哈!
备注:内容来源于stack exchange,提问作者Kevvv
相关产品推荐
相关产品推荐

