You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Docker Compose部署单节点MongoDB副本集无法连接,认证失败问题求助

Docker Compose部署单节点MongoDB副本集无法连接,认证失败问题求助

我来帮你分析下这个问题,你遇到的认证失败提示UserNotFound: Could not find user "dev" for db "mydb",主要是两个核心原因导致的:副本集初始化的配置问题,以及初始化脚本的执行时机不对。

问题根源拆解

  • 副本集节点地址配置错误:你在mongo-init.js里用了localhost:27017作为副本集节点地址,同时docker-compose里设置了hostname: localhost。但在Docker网络环境中,容器的localhost仅指向容器自身,副本集初始化时如果用这个地址,可能会导致节点状态无法正常就绪,后续创建用户的操作无法被持久化。
  • 用户创建时机过早:MongoDB启动副本集模式后,需要一点时间完成初始化流程,你的初始化脚本直接在rs.initiate()后就创建用户,此时副本集可能还没进入就绪状态,导致用户创建操作没有生效。

解决方案步骤

第一步:修正Docker Compose配置

先去掉多余的hostname: localhost配置(或者改为容器名mongo-database),让容器使用默认的网络标识:

version: "3.7"

services:
  mongo:
    container_name: mongo-database
    image: mongo:6.0.4
    restart: unless-stopped
    env_file:
      - .env
    ports:
      - "27017:27017"
    volumes:
      - ./mongo-init.js:/docker-entrypoint-initdb.d/mongo-init.js
    networks:
      - mongo-network
    command: ["--replSet", "rs0"]

networks:
  mongo-network:
    external: true

第二步:修改初始化脚本

更新mongo-init.js,用容器名作为副本集节点地址,并添加等待副本集就绪的逻辑,同时推荐在admin库创建全局root用户(更符合MongoDB的权限最佳实践):

// 初始化副本集,使用容器名作为节点地址,确保容器内部能正常识别
rs.initiate({ _id: 'rs0', members: [{ _id: 0, host: 'mongo-database:27017' }] })

// 循环等待副本集初始化完成,直到当前节点成为主节点
while (!rs.isMaster().ismaster) {
    print("等待副本集初始化完成...")
    sleep(1000)
}

// 在admin库创建root用户,拥有全局操作权限
db = db.getSiblingDB('admin')
db.createUser({
    user: 'dev',
    pwd: 'dev',
    roles: [{ role: 'root', db: 'admin' }]
})

// 给该用户授予mydb的所有者权限,确保能正常操作目标数据库
db = db.getSiblingDB('mydb')
db.grantRolesToUser('dev', [{ role: 'dbOwner', db: 'mydb' }])

第三步:更新连接URI

连接时需要指定认证数据库为admin,URI修改为:

mongodb://dev:dev@localhost:27017/mydb?replicaSet=rs0&authSource=admin

验证操作

  1. 先彻底清理旧的容器和数据卷(避免残留数据干扰):
docker-compose down -v
  1. 重新启动容器:
docker-compose up -d
  1. 查看容器日志,确认没有错误:
docker logs mongo-database

你应该能看到类似等待副本集初始化完成...的日志,以及用户创建成功的信息。
4. 用客户端测试连接:

mongosh "mongodb://dev:dev@localhost:27017/mydb?replicaSet=rs0&authSource=admin"

如果能正常进入MongoDB shell,说明问题解决了。

备注:内容来源于stack exchange,提问作者Magus

火山引擎 最新活动