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

如何正确将Mongo副本集容器与Node.js应用容器连接?

Node.js容器无法连接MongoDB容器的问题排查

问题描述

本地执行npm run start,使用连接字符串mongodb://localhost:27017/databaseDev?authSource=admin时能正常连接MongoDB,但通过Docker Compose部署的相同应用,使用mongodb://mongo:27017/databaseDev?authSource=admin却无法连接MongoDB。

提供的配置文件

docker-compose.yml

version: '3.5'

services:
  mongo:
    container_name: mongo
    image: mongo:4.4.15
    volumes:
      - ./mongodb/data:/data/db
      - ./mongodb/init-mongo.sh:/docker-entrypoint-initdb.d/init-mongo.sh
    ports:
      - 27017:27017
    environment:
      MONGO_INITDB_DATABASE: 'databaseDev'
    command: ["--replSet", "rs0", "--bind_ip_all"]

  api:
    container_name: api
    build:
      context: ./
      dockerfile: Dockerfile
    volumes:
      - ./:/var/app
      - /var/app/node_modules
    ports:
      - 3010:3010
    environment:
      PORT: 3010
      NODE_ENV: 'development'
      DB_HOST: 'mongo'
      DB_PORT: 27017
      DB_NAME: 'databaseDev'
depends_on:
      - mongo
    command: ['node', 'dist/main']

init-mongo.sh

mongo -- "$MONGO_INITDB_DATABASE" <<EOF
    rs.initiate();
    rs.status();
EOF

Dockerfile

FROM node:16.15.1 as build
WORKDIR /var/app
COPY . .
RUN npm ci
CMD ["node", "dist/main"]

问题排查与解决方法

1. Docker Compose配置缩进错误

你的docker-compose.yml中depends_on的缩进位置错误,它应该属于api服务的配置项,而非与services同级。错误的缩进会导致depends_on不生效,api容器可能在MongoDB容器完全启动前就开始运行。

修正后的api服务配置:

api:
  container_name: api
  build:
    context: ./
    dockerfile: Dockerfile
  volumes:
    - ./:/var/app
    - /var/app/node_modules
  ports:
    - 3010:3010
  environment:
    PORT: 3010
    NODE_ENV: 'development'
    DB_HOST: 'mongo'
    DB_PORT: 27017
    DB_NAME: 'databaseDev'
  depends_on:
    - mongo
  command: ['node', 'dist/main']

2. MongoDB副本集初始化不完整

depends_on仅保证MongoDB容器启动,不保证副本集初始化完成。Node应用启动时,MongoDB可能还在执行rs.initiate(),导致连接失败。

解决方法:

  • 在Node应用代码中添加连接重试逻辑,捕获连接错误并重试;
  • 使用等待脚本(如wait-for-it.sh)在启动Node应用前等待MongoDB副本集就绪,例如修改api服务的command:
    command: ["./wait-for-it.sh", "mongo:27017", "--", "node", "dist/main"]
    

3. 副本集初始化配置缺失主机名

当前init-mongo.sh中的rs.initiate()未指定主机名,默认会使用MongoDB容器的内部主机名(可能是容器ID),而Node应用连接的是服务名mongo,导致驱动无法识别副本集成员。

修改init-mongo.sh,明确指定副本集成员为mongo:27017:

mongo -- "$MONGO_INITDB_DATABASE" <<EOF
    rs.initiate({
        _id: "rs0",
        members: [
            { _id: 0, host: "mongo:27017" }
        ]
    });
    rs.status();
EOF

4. 连接字符串未指定副本集名称

因为MongoDB以副本集模式启动(--replSet rs0),但连接字符串中未声明副本集名称,Node驱动无法正确处理副本集连接。

修改连接字符串为:

mongodb://mongo:27017/databaseDev?authSource=admin&replicaSet=rs0

5. 容器网络连通性验证

如果上述方法无效,可进入api容器验证是否能解析mongo主机名:

docker exec -it api ping mongo

如果无法ping通,检查Docker网络配置,确保两个服务处于同一个默认网络中(Docker Compose默认会为所有服务创建并加入同一个网络)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 07:20:53