使用docker-compose部署后端与Mongo容器时遇ECONNREFUSED错误
问题:Docker Compose部署的Node应用无法连接MongoDB容器
执行docker-compose up后,Node应用容器启动约20秒后抛出连接拒绝错误,核心错误信息如下:
MongooseServerSelectionError: connect ECONNREFUSED 127.0.0.1:27017
完整错误日志:
(node:33) [MONGOOSE] DeprecationWarning: Mongoose: the `strictQuery` option will be switched back to `false` by default in Mongoose 7. Use `mongoose.set('strictQuery', false);` if you want to prepare for this change. Or use `mongoose.set('strictQuery', true);` to suppress this warning. (Use `node --trace-deprecation ...` to show where the warning was created) Server listening on port 3000 /cloudband/node_modules/mongoose/lib/connection.js:825 const serverSelectionError = new ServerSelectionError(); ^ MongooseServerSelectionError: connect ECONNREFUSED 127.0.0.1:27017 at Connection.openUri (/cloudband/node_modules/mongoose/lib/connection.js:825:32) at /cloudband/node_modules/mongoose/lib/index.js:409:10 at /cloudband/node_modules/mongoose/lib/helpers/promiseOrCallback.js:41:5 at new Promise (<anonymous>) at promiseOrCallback (/cloudband/node_modules/mongoose/lib/helpers/promiseOrCallback.js:40:10) at Mongoose._promiseOrCallback (/cloudband/node_modules/mongoose/lib/index.js:1262:10) at Mongoose.connect (/cloudband/node_modules/mongoose/lib/index.js:408:20) at Object.<anonymous> (/cloudband/server/server.js:15:4) at Module._compile (node:internal/modules/cjs/loader:1239:14) at Module._extensions..js (node:internal/modules/cjs/loader:1293:10) { reason: TopologyDescription { type: 'Unknown', servers: Map(1) { 'localhost:27017' => ServerDescription { address: 'localhost:27017', type: 'Unknown', hosts: [], passives: [], arbiters: [], tags: {}, minWireVersion: 0, maxWireVersion: 0, roundTripTime: -1, lastUpdateTime: 28094812, lastWriteDate: 0, error: MongoNetworkError: connect ECONNREFUSED 127.0.0.1:27017 at connectionFailureError (/cloudband/node_modules/mongodb/lib/cmap/connect.js:387:20) at Socket.<anonymous> (/cloudband/node_modules/mongodb/lib/cmap/connect.js:310:22) at Object.onceWrapper (node:events:628:26) at Socket.emit (node:events:513:28) at emitErrorNT (node:internal/streams/destroy:151:8) at emitErrorCloseNT (node:internal/streams/destroy:116:3) at process.processTicksAndRejections (node:internal/process/task_queues:82:21) { cause: Error: connect ECONNREFUSED 127.0.0.1:27017 at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1495:16) { errno: -111, code: 'ECONNREFUSED', syscall: 'connect', address: '127.0.0.1', port: 27017 }, [Symbol(errorLabels)]: Set(1) { 'ResetPool' } }, topologyVersion: null, setName: null, setVersion: null, electionId: null, logicalSessionTimeoutMinutes: null, primary: null, me: null, '$clusterTime': null } }, stale: false, compatible: true, heartbeatFrequencyMS: 10000, localThresholdMS: 15, setName: null, maxElectionId: null, maxSetVersion: null, commonWireVersion: 0, logicalSessionTimeoutMinutes: null }, code: undefined }
当前配置文件
Dockerfile
FROM node:19.4.0 WORKDIR /cloudband COPY package.json /cloudband/ COPY package-lock.json /cloudband/ RUN npm ci COPY .env /cloudband/ COPY server /cloudband/server/ EXPOSE 3000 CMD ["npm", "run", "dev:server"]
docker-compose.yml
version: '3' services: mongo: image: mongo container_name: mongo ports: - 27017:27017 environment: - MONGO_INITDB_ROOT_USERNAME=admin - MONGO_INITDB_ROOT_PASSWORD=password cloudband: image: cloudband container_name: cloudband ports: - 3000:3000 command: npm run dev:server networks: app:
已尝试的排查操作
- 确认容器处于同一网络且可互相ping通
- 在docker-compose中添加
links配置 - 检查端口、主机、IP配置
- 切换多种MONGO_URI格式:
# MONGO_URI_=mongodb://admin:password@localhost:27017/dbname MONGO_URI_=mongodb://localhost:27017/dbname # MONGO_URI_=mongodb://127.0.0.1:27017/dbname
解决方案
1. 修正MongoDB连接字符串
在Docker Compose的默认网络中,容器只能通过服务名互相访问,localhost或127.0.0.1指向容器自身,而非Mongo容器。同时因为你给Mongo配置了root用户名和密码,连接字符串必须包含认证信息,且指定认证源为admin数据库:
修改.env中的连接字符串:
MONGO_URI=mongodb://admin:password@mongo:27017/dbname?authSource=admin
2. 添加容器启动依赖
在docker-compose.yml的cloudband服务中添加depends_on,确保Mongo容器先于应用容器启动(注意:这仅保证启动顺序,不保证Mongo完全就绪):
cloudband: image: cloudband container_name: cloudband ports: - 3000:3000 command: npm run dev:server depends_on: - mongo
3. 处理MongoDB连接就绪等待
Mongo容器启动后需要几秒时间初始化,应用直接连接可能失败,可通过两种方式解决:
- 代码层面添加重试逻辑:在Mongoose连接配置中添加重试参数:
const mongoose = require('mongoose'); mongoose.connect(process.env.MONGO_URI, { retryWrites: true, w: 'majority', connectTimeoutMS: 10000, socketTimeoutMS: 45000, autoReconnect: true, maxPoolSize: 10 }); - 使用等待脚本:在应用启动命令前加入等待逻辑,确保Mongo端口就绪后再启动应用。修改
docker-compose.yml的command:
(若容器内无command: > sh -c "until nc -z mongo 27017; do echo waiting for mongo; sleep 2; done; npm run dev:server"netcat工具,需在Dockerfile中添加RUN apt-get update && apt-get install -y netcat)
4. 修复strictQuery警告(可选)
为消除Mongoose的deprecation警告,在应用启动代码(如server.js)中添加:
const mongoose = require('mongoose'); mongoose.set('strictQuery', false); // 或true,根据需求选择
内容的提问来源于stack exchange,提问作者John Donovan
相关产品推荐
相关产品推荐

