You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js容器连接MongoDB容器超时(MongoServerSelectionError)求助

问题描述

使用如下docker-compose.yaml部署Node.js和MongoDB服务:

version: '3.8'

networks:
  mongodb:
    name: mongodb
    driver: bridge
  host:
    name: host
    driver: host

services:
  nodejs-server:  
    networks:
      - mongodb
      - host
    build:
      context: ./api
      network: host
    ports:
      - "8000:8000"
    container_name: node-api
    volumes:
       - ./api:/usr/src/app/api
       - /usr/src/app/api/node_modules

mongodb:
    image: mongo
    networks:
      mongodb:
    container_name: mongodb
    ports:
      - 27017:27017
    restart: always
    environment:
      MONGO_INITDB_DATABASE: Demo
      MONGO_INITDB_ROOT_USERNAME: admin
      MONGO_INITDB_ROOT_PASSWORD: password

Express服务器index.js中的MongoDB连接代码:

const { MongoClient } = require('mongodb');
const mongoDB = 'mongodb://admin:password@mongodb:27017';
const mongoClient = new MongoClient(mongoDB);
app.get('/mongo', async (req, res) => {
    console.log('connecting...');
    await mongoClient.connect();
    console.log('connected...');
    const database = mongoClient.db('insertDB');
    const haiku = database.collection('haiku');
});

运行应用时,程序卡在await mongoClient.connect();,抛出异常:

MongoServerSelectionError: Server selection timed out after 30000 ms

但进入nodejs-server容器执行ping mongodb能正常连通:

/usr/src/app/api # ping mongodb
PING mongodb (172.21.0.2): 56 data bytes
64 bytes from 172.21.0.2: seq=0 ttl=64 time=0.146 ms
64 bytes from 172.21.0.2: seq=1 ttl=64 time=0.122 ms
64 bytes from 172.21.0.2: seq=2 ttl=64 time=0.199 ms
问题排查与解决方案

核心原因:多网络挂载的冲突

你的nodejs-server容器同时挂载了host网络和mongodb自定义bridge网络。当容器使用host网络时,会直接复用宿主机的网络栈,此时容器内的DNS解析优先走宿主机的DNS服务,而不是Docker自定义网络的内部DNS——这就导致MongoDB驱动无法通过容器名mongodb正确找到对应的服务实例,虽然ICMP协议的ping能通,但TCP连接无法正常建立。

具体修复步骤

  1. 移除host网络依赖
    修改docker-compose.yaml,给nodejs-server只保留mongodb网络,同时删掉无用的host网络定义:

    version: '3.8'
    
    networks:
      mongodb:
        name: mongodb
        driver: bridge
    
    services:
      nodejs-server:  
        networks:
          - mongodb
        build:
          context: ./api
          network: host
        ports:
          - "8000:8000"
        container_name: node-api
        volumes:
           - ./api:/usr/src/app/api
           - /usr/src/app/api/node_modules
    
      mongodb:
          image: mongo
          networks:
            mongodb:
          container_name: mongodb
          ports:
            - 27017:27017
          restart: always
          environment:
            MONGO_INITDB_DATABASE: Demo
            MONGO_INITDB_ROOT_USERNAME: admin
            MONGO_INITDB_ROOT_PASSWORD: password
    
  2. 完善MongoDB连接字符串
    因为启用了root用户,连接字符串需要指定认证数据库为admin,否则驱动无法完成身份校验:

    const mongoDB = 'mongodb://admin:password@mongodb:27017/?authSource=admin';
    
  3. 添加错误捕获逻辑
    在接口中加入错误处理,方便后续排查问题:

    app.get('/mongo', async (req, res) => {
        console.log('connecting...');
        try {
            await mongoClient.connect();
            console.log('connected...');
            const database = mongoClient.db('insertDB');
            const haiku = database.collection('haiku');
            res.send('MongoDB连接成功');
        } catch (err) {
            console.error('连接失败:', err);
            res.status(500).send('MongoDB连接失败');
        }
    });
    
  4. 重启服务
    执行命令重建并启动容器:

    docker-compose down
    docker-compose up --build
    

内容的提问来源于stack exchange,提问作者Teoman shipahi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 18:55:27