navicat填localhost连不上mysql,必须填127.0.0.1,因localhost触发unix socket连接而docker容器仅监听tcp端口;还需确保root@'%'权限已开、防火墙放行映射端口、-p参数正确映射宿主机端口。
navicat 填 localhost 就连不上,必须填 127.0.0.1
linux 版 navicat 在宿主机上运行时,填 localhost 会触发 mysql 的 unix socket 连接路径(/var/run/mysqld/mysqld.sock),而 docker 容器内的 mysql 并不监听该路径——它只监听 tcp 端口。结果 navicat 等不到响应,直接超时。
正确做法是:
- host 字段填 127.0.0.1(不是 localhost)
- port 字段填宿主机映射端口,比如 docker run -p 3307:3306,这里就填 3307
- 不要填容器 IP(如 172.17.0.2),那是 Docker bridge 内网地址,Linux 宿主机上的 Navicat 无法路由过去
MySQL root@% 权限没开,连通了也认证失败
即使网络通了,root@localhost 和 root@'127.0.0.1' 是两个独立账号。Docker 启动的 MySQL 默认只创建 root@localhost,不接受来自 127.0.0.1 的连接。
进容器执行以下命令:
mysql -uroot -p SELECT User, Host FROM mysql.user WHERE User='root';
若结果里没有 root@% 或 root@127.0.0.1,需手动添加:
CREATE USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'your_password';GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;FLUSH PRIVILEGES;
MySQL 8+ 用户还需注意:默认密码插件是 caching_sha2_password,Navicat 可能不兼容,所以显式指定 mysql_native_password
防火墙或 firewalld 拦住了宿主机端口
Linux 服务器(尤其是 CentOS/RHEL)默认启用 firewalld,即使 Docker 自动写入 iptables 规则,firewalld 仍可能拦截外部访问。
检查并放行端口:
-
sudo firewall-cmd --state(确认 firewalld 正在运行) -
sudo firewall-cmd --permanent --add-port=3306/tcp(把 3306 换成你实际映射的端口) sudo firewall-cmd --reload-
sudo firewall-cmd --list-all(验证端口已加入)
如果用的是 ufw(Ubuntu),对应命令是:sudo ufw allow 3306
Docker 启动时端口映射写错了
-p 参数漏写宿主机端口,是最隐蔽也最常踩的坑。例如:
- ❌
docker run -p 3306 mysql:8.0→ 只声明容器端口,宿主机端口由 Docker 随机分配,不可预测 - ✅
docker run -p 3306:3306 mysql:8.0→ 明确绑定宿主机 3306 到容器 3306 - ✅
docker run -p 5506:3306 mysql:8.0→ 宿主机用 5506 连,更安全(避开默认端口)
启动后用 docker port 确认映射关系;再用 netstat -tunlp | grep :3306 看宿主机是否真在监听该端口
真正卡住的地方往往不是密码或驱动版本,而是 host 填错、权限没开、防火墙挡着、或者 -p 写得不完整——四者缺一不可。每改一项,都建议用 telnet 127.0.0.1 端口号 先验证端口可达性,再开 Navicat 测试。











