navicat连不上docker mysql,八成是host填localhost(触发socket连接)而非127.0.0.1,且port未匹配宿主机映射端口(如-p 3307:3306时需填3307),同时root@localhost与root@127.0.0.1是两个独立用户,须显式授权。
navicat 连不上 docker mysql,八成是 host 和 port 填错了
根本原因不是密码错、不是权限没开,而是 navicat 发的是 tcp 请求,而你填了 localhost —— mysql 在 linux/macos 下看到 localhost 会直接走 socket 文件,压根不监听 tcp;windows 下则可能走命名管道。结果 navicat 干等响应,超时失败。
必须填 127.0.0.1(或服务器真实 IP),且端口必须对应宿主机上暴露的端口,不是容器内部的 3306。
- 运行容器时用了
-p 3307:3306?Navicat 的端口就填3307 - 用了
-p 0.0.0.0:3306:3306或默认绑定?端口填3306,host 填127.0.0.1(本机连)或服务器公网 IP(远程连) - 没做端口映射(比如只写了
-p 3306)?容器端口根本没暴露,Navicat 必然连接拒绝
docker run 时端口映射写法必须明确宿主机端口
-p 参数格式是 宿主机IP:宿主机端口:容器端口,中间两个冒号可省略 IP,但「宿主机端口:容器端口」不能少。MySQL 容器内固定用 3306,所以重点在左边那个数字。
- 正确:
docker run -p 3306:3306 mysql:5.7→ 宿主机 3306 映射到容器 3306 - 也正确:
docker run -p 5506:3306 mysql:5.7→ Navicat 连127.0.0.1:5506 - 错误:
docker run -p 3306 mysql:5.7→ 只声明容器端口,没指定宿主机端口,Docker 随机分配(docker port才能查到),不可控 - 危险:
docker run -p 0.0.0.0:3306:3306→ 绑定到所有网卡,若服务器没关防火墙或没设安全组,等于裸奔
别用 Docker 默认网桥 IP 直连 MySQL 容器
有人查 docker inspect 看到 "IPAddress": "172.17.0.2",就想在 Navicat 里填这个 IP + 3306 —— 行不通。这是 Docker 内部 bridge 网络地址,宿主机以外的机器访问不到,Navicat 在 Windows/macOS 本地跑,根本路由不过去。
唯一例外:Navicat 装在同台 Linux 服务器上,且你确认 iptables 或 nftables 没拦截 172.17.0.0/16 流量 —— 但这种绕过端口映射的做法毫无必要,还增加排障成本。
- 坚持用
-p映射到宿主机端口,最稳 - 如果真要用容器 IP,得改用
host网络模式(--network host),但此时容器共享宿主机网络栈,端口冲突风险高,且 MySQL 默认 bind-address 是127.0.0.1,仍需手动改配置
用户名 root@localhost 和 root@127.0.0.1 是两个用户
MySQL 把 root@localhost 和 root@127.0.0.1 当作完全不同的账号,授权记录分开存。Docker 启动时设置的 MYSQL_ROOT_PASSWORD 默认只创建 root@localhost,而 Navicat 填 127.0.0.1 就是在连 root@127.0.0.1 —— 密码对也不认。
解决方法只有两个:
- 启动容器时加
-e MYSQL_ROOT_HOST=%(不推荐,权限过大) - 容器启动后进 MySQL 执行:
CREATE USER 'root'@'127.0.0.1' IDENTIFIED BY 'xxx'; GRANT ALL ON *.* TO 'root'@'127.0.0.1' WITH GRANT OPTION;,再FLUSH PRIVILEGES; - 或者干脆在 Navicat 里把 host 改成
localhost—— 但前提是你的操作系统支持 socket 连接,且 Navicat 版本 >= 15(旧版不支持 socket)
真正容易被忽略的是:即使你改了 MySQL 配置让 bind-address = 0.0.0.0,只要没显式创建 root@127.0.0.1 这个账号,Navicat 就永远提示“Access denied”。











