Docker容器中NestJS+TypeORM无法连接MySQL数据库问题
解决NestJS容器连接MySQL容器失败的问题
核心问题分析
报错显示连接127.0.0.1:3306被拒绝,说明你的NestJS服务实际在尝试连接容器自身的3306端口,而非local_db容器的端口;或者MySQL服务还未完成初始化,NestJS就发起了连接请求。
分步解决方案
1. 确保.env变量被容器正确读取
你的Docker Compose未配置将本地.env文件注入到server容器,导致NestJS可能无法读取到DB_HOST=local_db的配置,进而使用默认的127.0.0.1。修改Docker Compose的server服务:
services: server: build: context: . dockerfile: Dockerfile ports: - 8000:8000 volumes: - .:/server-workdir - '/server-workdir/node_modules' depends_on: - local_db env_file: # 新增配置,加载本地.env文件 - .env
2. 统一TypeOrm配置使用环境变量
你当前TypeOrm配置中host是硬编码的"local_db",建议改为读取环境变量,避免硬编码与配置文件不一致:
TypeOrmModule.forRoot({ type: "mysql", host: process.env.DB_HOST, // 替换硬编码值 port: parseInt(process.env.DB_PORT), username: process.env.DB_USERNAME, password: process.env.DB_PASSWORD, database: process.env.DB_NAME, entities: [], synchronize: true, }),
3. 等待MySQL服务完全就绪
depends_on仅保证local_db容器先启动,但MySQL第一次启动时需要初始化数据库、配置权限,这个过程需要时间。可以通过两种方式处理:
方式一:使用wait-for-it脚本(推荐)
- 下载脚本到项目根目录:
curl -o wait-for-it.sh https://raw.githubusercontent.com/vishnubob/wait-for-it/master/wait-for-it.sh chmod +x wait-for-it.sh
- 修改Dockerfile的启动命令:
CMD [ "./wait-for-it.sh", "local_db:3306", "--", "yarn", "dev" ]
方式二:增加TypeOrm重试配置
给MySQL足够的初始化时间,修改TypeOrm配置:
TypeOrmModule.forRoot({ type: "mysql", host: process.env.DB_HOST, port: parseInt(process.env.DB_PORT), username: process.env.DB_USERNAME, password: process.env.DB_PASSWORD, database: process.env.DB_NAME, entities: [], synchronize: true, retryAttempts: 10, // 增加重试次数 retryDelay: 3000, // 重试间隔3秒 }),
4. 验证网络连通性(排查用)
如果以上步骤无效,进入NestJS容器测试是否能访问local_db:
# 查看server容器名称 docker ps # 进入容器 docker exec -it <server-container-name> /bin/bash # 测试ping连通性 ping local_db # 测试MySQL连接 mysql -h local_db -u root -proot
如果无法连通,显式定义Docker网络:
version: '3.9' networks: app-network: driver: bridge services: server: build: context: . dockerfile: Dockerfile ports: - 8000:8000 volumes: - .:/server-workdir - '/server-workdir/node_modules' depends_on: - local_db env_file: - .env networks: - app-network local_db: container_name: "local_db" image: mysql:8.0 ports: - 3306:3306 environment: - MYSQL_DATABASE=local - MYSQL_PASSWORD=root - MYSQL_ROOT_PASSWORD=root networks: - app-network
验证
修改完成后重启服务:
docker-compose down docker-compose up --build
观察日志,若NestJS成功连接MySQL则问题解决。
内容的提问来源于stack exchange,提问作者Aaron56
相关产品推荐
相关产品推荐

