使用Node.js+MongoDB开发RESTful API时遇getaddrinfo ENOTFOUND db错误求助
解决'getaddrinfo ENOTFOUND db'错误的方案
1. 核对MongoDB连接字符串
你的Node.js代码里必须用容器服务名db作为连接地址,不能用localhost或127.0.0.1——Docker Compose默认网络里,容器之间通过服务名互相识别。
正确的连接字符串示例:
// MongoDB原生驱动 const uri = 'mongodb://root:example@db:27017/your-db-name?authSource=admin'; // Mongoose框架 const uri = 'mongodb://root:example@db:27017/your-db-name?authSource=admin';
注意替换your-db-name为实际数据库名,同时确保用户名、密码和docker-compose里的MONGO_INITDB_ROOT_USERNAME、MONGO_INITDB_ROOT_PASSWORD完全一致。
2. 验证Docker Compose网络
Docker Compose会自动给所有服务创建默认网络,正常情况下容器能通过服务名互通。如果之前修改过网络配置,确保app和db在同一个网络里。当前配置没问题的话,可重启整个服务重置网络:
docker-compose down docker-compose up -d --build
3. 处理数据库启动延迟
depends_on仅保证db容器先启动,但不保证MongoDB服务完全就绪。如果应用启动时数据库还在初始化,就会触发连接失败。
解决办法有两种:
- 在Node.js代码里加自动重连逻辑:
const mongoose = require('mongoose'); const uri = 'mongodb://root:example@db:27017/your-db-name?authSource=admin'; const connectWithRetry = () => { mongoose.connect(uri) .then(() => console.log('MongoDB连接成功')) .catch(err => { console.log('连接失败,5秒后重试...', err); setTimeout(connectWithRetry, 5000); }); }; connectWithRetry();
- 给
db服务加健康检查,让app等数据库真正就绪后再启动:
修改docker-compose.yml里的db配置:
db: image: 'mongo:latest' restart: always environment: MONGO_INITDB_ROOT_USERNAME: root MONGO_INITDB_ROOT_PASSWORD: example ports: - '27017:27017' volumes: - mongo-data:/data/db healthcheck: test: ["CMD", "mongosh", "--eval", "db.adminCommand('ping')"] interval: 5s timeout: 5s retries: 5
再修改app的depends_on:
app: build: . restart: always ports: - 5000:5000 depends_on: db: condition: service_healthy
4. 检查容器DNS解析
如果以上都没用,进入app容器测试DNS是否能识别db:
# 替换your-app-container-name为实际容器名 docker exec -it your-app-container-name sh # 尝试ping db ping db
如果ping不通,说明DNS配置异常,可重启Docker服务或检查Docker的DNS设置。
内容的提问来源于stack exchange,提问作者Mehmet Ali
相关产品推荐
相关产品推荐

