Docker容器连接宿主机localhost报连接被拒的解决方案咨询
Docker Compose部署场景下容器访问宿主机MySQL连接被拒修复方案
前置排查:先解决宿主机侧的访问限制
- 检查MySQL监听地址配置
90%以上的同类报错都是这一步配置错误导致的,不要上来先修改容器内的连接地址- 默认MySQL安装后会绑定
127.0.0.1作为监听地址,这种情况下MySQL只会响应宿主机本地的回环请求,来自Docker网桥的请求会被直接拒绝 - 打开MySQL配置文件(常见路径为
/etc/mysql/mysql.conf.d/mysqld.cnf或/etc/my.cnf),找到bind-address配置项:- 测试环境可以直接改为
bind-address = 0.0.0.0,监听所有网卡地址 - 生产环境建议绑定Docker网桥网关地址
172.17.0.1,仅暴露给Docker网段访问
- 测试环境可以直接改为
- 执行
sudo systemctl restart mysql重启服务生效,之后在宿主机执行ss -tulpn | grep 3306验证,如果输出中存在0.0.0.0:3306或你绑定的对应IP:3306处于LISTEN状态才算配置生效
- 默认MySQL安装后会绑定
- 检查宿主机防火墙规则
Ubuntu默认启用的ufw防火墙会默认拒绝Docker网桥网段的入站请求,执行以下命令放通对应流量:
如果使用firewalld或其他安全防护软件,也要对应添加规则放通Docker网段对3306端口的访问。# 放通Docker网桥网段访问宿主机3306端口的权限 sudo ufw allow in on docker0 to any port 3306 from 172.17.0.0/16 sudo ufw reload
容器侧连接地址正确配置(针对Ubuntu环境)
你之前尝试的两种方案失效,基本都是因为宿主机侧限制没放开,这里给docker-compose场景下的稳定配置方式,不建议硬编码172.17.0.1——这个地址是Docker默认网桥的网关,如果你在compose里自定义了网络,该地址会变化,硬编码极易失效。
Linux环境下host.docker.internal域名默认不会自动解析,需要在docker-compose.yml中给对应微服务添加手动映射配置:
services: 你的微服务名称: image: 你的服务镜像地址 # 新增以下配置 extra_hosts: - "host.docker.internal:host-gateway"
配置完成后执行docker-compose up -d重启服务,容器内就可以通过host.docker.internal:3306稳定访问宿主机的MySQL服务,该配置兼容所有Docker 20.10以上版本,不受自定义网络影响。
最后校验MySQL账号权限
网络打通后如果仍然连接失败,需要检查MySQL账号的访问权限:
- 登录宿主机MySQL,执行以下SQL查看账号允许的访问来源:
select user,host from mysql.user; - 如果你的业务账号对应的host值为
localhost或127.0.0.1,则该账号不允许来自Docker网段的连接,执行以下SQL授权即可(替换其中的账号、密码、业务库名为你实际的配置):-- 允许业务账号从Docker网段访问 CREATE USER '你的业务账号'@'172.17.0.0/255.255.0.0' IDENTIFIED BY '你的账号密码'; GRANT ALL PRIVILEGES ON 你的业务库名.* TO '你的业务账号'@'172.17.0.0/255.255.0.0'; FLUSH PRIVILEGES;
注意:生产环境不要为了省事给账号配置
%任意来源访问权限,必须严格限制访问来源网段,避免数据库暴露带来的安全风险。
你可以通过临时启动一个MySQL客户端容器验证连通性,命令执行后能正常进入MySQL命令行就说明所有配置生效:
docker run --rm --network 你的compose项目使用的网络名 mysql:8.0 mysql -h host.docker.internal -P3306 -u你的业务账号 -p你的账号密码
内容的提问来源于stack exchange,提问作者Kushwaha
相关产品推荐
相关产品推荐

