使用NestJS的MongooseModule.forRootAsync连接Mongo时遇DNS错误排查
问题
无法通过MongooseModule.forRootAsync异步连接本地MongoDB,相关配置如下:
全局ConfigModule配置:
ConfigModule.forRoot({ isGlobal: true, envFilePath: ['.env'], cache: false, }),
Mongoose异步连接配置:
MongooseModule.forRootAsync({ imports: [ConfigModule], useClass: MongodbConfigService, })
配置类代码:
@Injectable() export class MongodbConfigService implements MongooseOptionsFactory { constructor(private readonly configService: ConfigService) {} createMongooseOptions(): | MongooseModuleOptions | Promise<MongooseModuleOptions> { console.log(this.configService.get<string>('MONGODB_HOST')); // 输出:mongodb://localhost:27017/mydb return { uri: this.configService.get<string>('MONGODB_HOST'), useNewUrlParser: true, }; } }
执行npm run start:dev启动应用时出现错误:
querySrv ENOTFOUND _mongodb._tcp.cluster0.lys1va8.mongodb.net
Error: querySrv ENOTFOUND _mongodb._tcp.cluster0.lys1va8.mongodb.net
at QueryReqWrap.onresolve [as oncomplete] (node:internal/dns/promises:173:17)
.env文件配置的是本地Docker MongoDB地址:
MONGODB_HOST=mongodb://localhost:27017/mydb
疑问:错误中的_mongodb._tcp.cluster0.lys1va8.mongodb.net是之前用过的Atlas地址,它来自哪里?会不会是NestJS的缓存?
解决方案
- 排查重复的Mongoose连接配置:检查项目所有模块,确认是否有其他地方调用
MongooseModule.forRoot()并硬编码了旧的Atlas连接地址。NestJS中多份Mongoose连接配置可能引发冲突,导致旧地址被优先加载。 - 清理编译与依赖缓存:删除项目根目录的
dist文件夹(NestJS编译产物),同时删除node_modules和package-lock.json,重新执行npm install后再启动应用。 - 验证环境变量优先级:检查系统级环境变量中是否存在同名的
MONGODB_HOST——部分系统会优先读取系统环境变量,覆盖本地.env文件配置。可通过echo $MONGODB_HOST(Linux/macOS)或echo %MONGODB_HOST%(Windows)查看实际生效的变量值。 - 强制固定连接地址测试:在
createMongooseOptions方法中直接返回固定的本地URI,验证是否能正常连接:
若此方式可连接,说明问题出在ConfigService变量读取逻辑;若仍报错,需继续排查项目中未被发现的旧连接配置。return { uri: 'mongodb://localhost:27017/mydb', useNewUrlParser: true, }; - 检查Docker网络映射:若MongoDB运行在Docker容器中,确认容器27017端口已正确映射到本地,且应用与容器处于同一网络环境(比如使用Docker Compose编排共享网络)。
内容的提问来源于stack exchange,提问作者Rafa Acioly
相关产品推荐
相关产品推荐

