是,docker ps的ports列必须显示0.0.0.0:3306->3306/tcp;若为32768->3306/tcp或127.0.0.1:3306,则端口未正确映射或绑定,navicat无法连接。

docker ps 显示的 PORTS 列是不是 0.0.0.0:3306->3306/tcp?
这是最常被跳过的一步。Navicat 连不上,90% 是因为 docker ps 的 PORTS 列压根没显示你期望的映射。运行 docker ps 后如果看到的是 32768->3306/tcp 或者空着,说明容器启动时只写了 -p 3306,Docker 随机分配了宿主机端口——你根本不知道该连哪个。
必须用显式绑定:docker run -p 0.0.0.0:3306:3306(或 -p 3307:3306 避开冲突)。验证方式:docker port 输出应为 3306/tcp -> 0.0.0.0:3306;若输出是 127.0.0.1:3306,Mac 上 Navicat 仍连不上,因为 Docker Desktop for Mac 的网络栈不转发 127.0.0.1 绑定的端口。
MySQL 容器内用户是否允许远程连接且认证插件兼容?
MySQL 8+ 默认创建的 'root'@'localhost' 只响应 Unix socket 或容器内 127.0.0.1 请求,而 Navicat 从 Mac 发起的是 TCP 连接,目标 host 是宿主机 IP,所以必须有 'root'@'%' 或 'root'@'172.17.%' 这类通配 host 的用户。
- 进容器执行:
mysql -u root -p -e "SELECT host,user,plugin FROM mysql.user;" - 若 plugin 是
caching_sha2_password,Navicat 16.3.7 旧版本可能不支持,需改回:ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'your_password'; - 别忘了刷新权限:
FLUSH PRIVILEGES;
Navicat 连接参数里 host 填 localhost 还是 127.0.0.1?
在 macOS 上,填 localhost 大多数情况能通,但本质依赖 Docker Desktop 的 DNS 解析机制;一旦出问题,127.0.0.1 更稳定——它强制走 TCP,绕过 Unix socket 解析歧义。
Port 字段必须严格等于 docker run -p 左侧的宿主机端口号(比如 -p 3307:3306 就填 3307),不能想当然填容器内端口。
Database 字段不能为空;若启动容器时指定了 -e MYSQL_DATABASE=myapp,这里就必须填 myapp,大小写敏感。
telnet localhost 3306 超时说明什么?
在 Mac 终端执行 telnet localhost 3306 或 nc -zv localhost 3306,如果直接超时或报 Connection refused,说明连接请求根本没抵达 MySQL 进程——问题一定出在 Docker 网络层或宿主机端口绑定上,和 Navicat 配置、密码、SSL 设置都无关。
此时不用打开 Navicat,先确认:
-
docker port是否返回0.0.0.0:3306 -
docker inspect中"HostConfig": {"PortBindings": {"3306/tcp": [{"HostIp": "0.0.0.0", ...}]}是否存在且 HostIp 是0.0.0.0 - 容器内是否监听
0.0.0.0:3306:进容器跑netstat -tlnp | grep :3306,看到*:3306才对
这些点全对了,Navicat 还连不上,那大概率是防火墙或 Docker Desktop 自身转发链路异常——M1/M2 Mac 用户尤其要注意虚拟机网络状态是否正常,重启 Docker Desktop 常比重启容器更有效。











