Docker 容器为什么连不上宿主机 MySQL?

容器里的 localhost 指向自己。分清数据库位置,再检查服务名、宿主机地址、监听接口和账号 Host 权限。

应用放进 Docker,原来的 localhost:3306 连不上了,通常先要改数据库地址。容器里的 localhost 指向应用容器自己,无法借这个地址连接宿主机或另一个数据库容器。

两个容器在同一网络,用服务名

应用与数据库在同一 Compose 项目、同一网络时,数据库主机填服务名,例如 db,端口用数据库容器内部端口 3306。宿主机发布出来的端口用于从宿主机地址访问,不替代同网络内的服务端口。

查看现有项目,确认应用和数据库是否真的共享网络。不要把容器的临时 IP 写进长期配置;重新创建后地址可能改变。

MySQL 在 Linux 宿主机,给它建立可达名称

将下面片段合并到现有应用服务,镜像名称保留原项目实际使用的值:

services:
  app:
    image: your-application-image:your-tag
    extra_hosts:
      - "host.docker.internal:host-gateway"

把应用的数据库地址改为 host.docker.internal:3306,然后检查 Compose 配置并重建应用容器。这个名称映射解决的是宿主机地址,不会自动调整 MySQL 监听、账号权限或防火墙。

连接拒绝与超时,先查监听

在宿主机只读查看端口:

sudo ss -lntp | grep 3306

MySQL 只监听 127.0.0.1 时,容器通过网桥地址无法连接。按实际部署方式调整到允许的宿主机接口,限制访问来源;不要把 3306 对整个公网开放。

连接拒绝通常先看目标地址、端口及服务是否监听;超时再检查路由和防火墙。最终验证要从应用所在容器使用相同地址完成,只在宿主机连通还不够。

Access denied,检查用户和 Host

数据库已经返回认证错误时,检查用户名、密码及 MySQL 账号的 Host 限制。数据库看到的连接来源可能是容器网络地址,不能把宿主机本地登录成功当作该账号也允许容器访问。

为应用使用独立账号,只授予对应业务库的权限。配置改变后重新创建应用容器,并查看新日志;已有错误不会因为清空日志而解决。

修好连接后,再看要不要拆分数据库

数据库连不上,先按地址、监听、账号与权限排查,加内存不会把错误的地址改对。确认应用和数据库长期竞争资源以后,再看整套服务的内存选择;云数据库与应用需要同平台连接时,也要把网络成本一起比较。

若准备将数据库与应用拆到不同实例,优先考虑同地域的受控内网、备份位置与连接延迟,而不是分别买两台最低价机器。已有云资源时,可查看 ECS 的地域与网络组合;小型单机部署则可比较 雨云 RCS 的应用配置。买之前确认两台实例怎样互通,账号、监听地址和权限错误仍要先修复。