Docker部署Nginx反向代理MySQL无法连接问题求助
问题:Nginx Stream反向代理MySQL无法连接的排查与解决
问题描述
我通过Docker Compose部署了Nginx和MySQL容器,配置Nginx的stream模块反向代理MySQL,将宿主机33060端口映射至Nginx容器3306端口,但无法通过该端口连接MySQL。取消MySQL容器的3307:3306端口映射注释后,可正常通过3307端口访问。两个容器处于同一nginx-mysql网络,疑惑是否误解了Docker网络的功能,或是配置文件存在错误?另外,两个容器在同一个docker-compose文件中,是否无需手动配置networks?
配置文件
docker-compose.yaml
services: nginx: image: nginx:1.23.3 container_name: nginx volumes: - /lnmpg/nginx/conf.d:/etc/nginx/conf.d:ro,cached - /lnmpg/nginx/nginx.conf:/etc/nginx/nginx.conf :ro - /lnmpg/nginx/log:/var/log/nginx - /lnmpg/nginx/html:/usr/share/nginx/html ports: - "80:80" - "443:443" - "33060:3306" environment: - TZ=Asia/Shanghai restart: always networks: - nginx-mysql mysql: image: mysql:5.7.41 # ports: # - "3307:3306" environment: - TZ=Asia/Shanghai - MYSQL_ROOT_PASSWORD=Xqw@1023 volumes: - /lnmpg/mysql/init:/docker-entrypoint-initdb.d - /lnmpg/mysql/my.cnf:/etc/mysql/my.cnf :ro - /lnmpg/mysql/data:/var/lib/mysql - /lnmpg/mysql/log:/var/log/mysql restart: always networks: - nginx-mysql
nginx.conf
stream { log_format basic '$remote_addr [$time_local] ' '$protocol $status $bytes_sent $bytes_received ' '$session_time'; access_log logs/stream-access.log debug buffer=32k; server { listen 33060; proxy_pass mysql:3306; } } http { include /etc/nginx/mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; #tcp_nopush on; keepalive_timeout 65; #gzip on; include /etc/nginx/conf.d/*.conf; }
问题分析与解决方案
1. 核心配置错误
你的Nginx stream配置存在端口不匹配的问题:
- Docker Compose中,Nginx的端口映射是
33060:3306,意味着宿主机33060端口的流量会转发到Nginx容器内部的3306端口。 - 但你在
nginx.conf的stream模块里配置的是listen 33060;,这会导致Nginx在容器内部监听33060端口,而容器的3306端口根本没有服务监听,自然无法接收宿主机转发过来的流量。
修正方法:将stream模块中的监听端口改为3306,修改后的stream配置如下:
stream { log_format basic '$remote_addr [$time_local] ' '$protocol $status $bytes_sent $bytes_received ' '$session_time'; access_log logs/stream-access.log debug buffer=32k; server { listen 3306; # 改为容器内部的3306端口 proxy_pass mysql:3306; } }
2. Docker网络相关疑问
- 同一docker-compose文件中的服务,即使不手动配置networks,Docker Compose也会自动创建一个默认网络(以当前项目目录名为前缀),服务之间可以通过服务名(如
mysql)互相访问。你手动指定nginx-mysql网络是完全可行的,这部分配置没有问题,Nginx通过mysql:3306访问MySQL容器是正常的。
3. MySQL端口映射的作用
取消MySQL的3307:3306映射注释后能正常访问,是因为流量直接绕过Nginx,从宿主机3307端口转发到MySQL容器的3306端口,和Nginx代理路径无关,这也证明MySQL容器本身是正常运行的。
内容的提问来源于stack exchange,提问作者StupidPz
相关产品推荐
相关产品推荐

