Docker部署Python连接MySQL报Unknown MySQL server host 'db'错误排查
问题根因
报错2005 (HY000): Unknown MySQL server host 'db' (-3)的核心原因是Docker Compose网络隔离:
你手动定义了名为local的自定义桥接网络,web和backend服务都明确加入了该网络,但db服务没有配置网络归属,默认会加入Compose自动生成的默认网络,和backend不在同一网络平面,DNS解析自然无法找到db这个主机名。
之前尝试用localhost连接失败是正常现象:容器内的localhost指向容器自身,既不代表宿主机,也不代表同主机上的其他容器。
修复步骤
- 给
db服务补充网络配置,将其加入local网络,和backend处于同一网络平面。修改docker-compose.yml中db服务段,新增networks配置:
db: container_name: db image: mysql restart: unless-stopped volumes: - ./mysql:/docker-entrypoint-initdb.d environment: - MYSQL_ROOT_PASSWORD=password - MYSQL_DATABASE=database - MYSQL_USER=user - MYSQL_PASSWORD=password ports: - 3306:3306 networks: - local
- 删除docker-compose.yml顶层volumes中冗余的
db卷声明:你当前db服务使用的是./mysql目录的绑定挂载,这个自定义的db卷没有被任何服务引用,属于无效配置。 - 去掉硬编码的数据库连接参数,改为从环境变量读取。当前backend服务只传入了DB_PASSWORD环境变量,建议把所有数据库连接参数都通过环境变量注入,后续调整配置不需要修改代码:
首先修改backend服务的environment配置:
再修改app.py中的数据库连接逻辑,读取环境变量:backend: container_name: app build: flask environment: - FLASK_SERVER_PORT=9091 - DB_HOST=db - DB_PORT=3306 - DB_USER=user - DB_PASSWORD=password - DB_NAME=database volumes: - flask:/tmp/app_data restart: unless-stopped networks: - local depends_on: - db
注:配置里的import os conn = mysql.connector.connect( host=os.getenv("DB_HOST", "db"), port=int(os.getenv("DB_PORT", 3306)), user=os.getenv("DB_USER", "user"), password=os.getenv("DB_PASSWORD", "password"), database=os.getenv("DB_NAME", "database"))links: - db属于旧版Docker默认桥接网络的遗留配置,在自定义网络下不需要,自定义桥接网络默认内置服务DNS解析能力,留着也不会报错,可以自行删除。 - 注意
depends_on仅能控制容器的启动顺序,不会等待MySQL服务完成初始化。如果app启动时MySQL还在初始化流程中,首次连接依然可能报错,建议在app启动逻辑中添加数据库连接重试机制,或者引入wait-for-it类脚本检测到db端口正常监听后再启动应用。 - 配置修改完成后,执行以下命令重建并启动服务:
docker compose down docker compose up -d --build
内容的提问来源于stack exchange,提问作者carapau
相关产品推荐
相关产品推荐

