如何配置docker-compose使localhost:3306访问MySQL容器?
首先咱们得捋清楚核心矛盾:你的本地Ubuntu主机上的MySQL8.0已经占用了localhost:3306,而Docker容器默认的端口映射是绑定所有网卡(0.0.0.0:3306),这就导致用localhost连接时会优先命中本地的MySQL8.0,而非容器里的5.6。要实现你的需求,有两种靠谱方案,优先推荐第一种(长期稳定):
方案一:调整本地MySQL端口+Docker绑定localhost
这是最直接且无后顾之忧的方案,只需改动两处配置:
1. 让本地MySQL8.0让出localhost:3306
编辑本地MySQL的配置文件(通常路径是/etc/mysql/mysql.conf.d/mysqld.cnf):
- 找到
port = 3306,把它改成port = 3307(或者其他未被占用的端口) - 确认
bind-address设置为127.0.0.1(确保本地MySQL只监听本机,不对外暴露)
保存配置后,重启本地MySQL服务:
sudo systemctl restart mysql
现在本地MySQL8.0会监听localhost:3307,localhost:3306就空闲出来了。
2. 修改Docker Compose配置,绑定localhost的3306端口
把你的docker-compose.yaml里的ports部分修改为:
ports: # 仅绑定主机的127.0.0.1(即localhost)的3306端口到容器内部3306 - '127.0.0.1:3306:3306'
原来的3306:3306是绑定所有网卡,改成127.0.0.1:3306:3306后,只有本机的localhost请求会被转发到容器的MySQL5.6。
3. 重启容器生效
执行以下命令重新部署容器:
docker-compose down docker-compose up -d
验证
现在用命令测试连接容器的MySQL5.6:
mysql -h localhost -P 3306 -u myuser -p
输入密码后应该能成功连接;本地的MySQL8.0可以通过mysql -h localhost -P 3307 -u root -p访问,两者互不干扰。
方案二:用iptables端口转发(无需修改本地MySQL)
如果你实在不想调整本地MySQL的端口,可以用iptables把localhost:3306的流量转发到容器内部,但这个方案的缺点是容器重启后内部IP可能变化,需要重新配置:
1. 获取容器的内部IP
执行命令找到容器的私有IP:
docker inspect sciodb | grep "IPAddress"
输出大概是"IPAddress": "172.17.0.2"这样的格式,记下这个IP。
2. 添加iptables转发规则
执行以下命令添加NAT转发规则:
sudo iptables -t nat -A OUTPUT -d 127.0.0.1 -p tcp --dport 3306 -j DNAT --to-destination 172.17.0.2:3306
这条规则的作用是:把所有发往127.0.0.1:3306的TCP请求,转发到容器的内部IP的3306端口。
注意事项
- 如果容器重启,内部IP大概率会变更,需要重新执行步骤1和2更新规则
- 若要永久保存iptables规则,需要用
iptables-save工具(比如sudo iptables-save > /etc/iptables/rules.v4)
内容的提问来源于stack exchange,提问作者Toskan

