Docker容器中Express服务无法连接同网络MySQL容器求助
解决Docker容器间MySQL连接失败(EAI_AGAIN db)问题
针对你遇到的Express容器无法通过容器名db连接MySQL容器的问题,给你几个排查和解决方向:
1. 验证容器网络归属
虽然docker-compose配置里两个服务都指定了whole-application网络,但偶尔会出现容器未正确加入网络的情况。执行以下命令检查:
# 查看db容器的网络信息 docker inspect db | grep -A 10 Networks # 查看product-service容器的网络信息 docker inspect product-service | grep -A 10 Networks
确保两个容器的whole-application网络配置一致,没有遗漏。如果不一致,重新执行docker-compose down -v && docker-compose up --build重建网络和容器。
2. 处理MySQL服务未就绪的问题
depends_on仅保证db容器先启动,但不保证MySQL服务完全初始化完成。Express启动时可能MySQL还没准备好,导致连接失败。解决方法:
- 在代码中添加重试逻辑:修改database.js,连接失败时自动重试,示例:
const mysql = require('mysql'); function createConnection() { const connection = mysql.createConnection({ host: 'db', user: 'root', password: 'root', database: 'footballplayers' }); connection.connect((err) => { if (err) { console.error('连接失败,1秒后重试:', err); setTimeout(createConnection, 1000); return; } console.log('数据库连接成功'); }); return connection; } module.exports = createConnection();
- 在启动脚本中加入等待逻辑:使用
wait-for-it工具(需要在Dockerfile中安装),修改package.json的start命令:
"scripts": { "start": "wait-for-it db:3306 -- node app.js" }
3. 确认MySQL允许远程连接
自定义的mysql_db镜像可能默认只允许本地连接,需要确保root用户可以从任意主机连接。在构建MySQL镜像时,添加以下SQL命令:
ALTER USER 'root'@'%' IDENTIFIED BY 'root'; FLUSH PRIVILEGES;
可以把这段命令放在初始化脚本中(比如/docker-entrypoint-initdb.d/下的.sql文件),让MySQL启动时自动执行。
4. 测试容器间连通性
进入product-service容器,测试与db的连通性:
# 进入容器 docker exec -it product-service sh # ping db容器,测试DNS解析 ping db # 测试3306端口是否开放 telnet db 3306
如果ping不通,说明网络存在问题;如果ping通但telnet失败,说明MySQL服务未正常启动或端口未暴露。
内容的提问来源于stack exchange,提问作者Ambicatus
相关产品推荐
相关产品推荐

