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
验证操作
- 先彻底清理旧的容器和数据卷(避免残留数据干扰):
docker-compose down -v
- 重新启动容器:
docker-compose up -d
- 查看容器日志,确认没有错误:
docker logs mongo-database
你应该能看到类似等待副本集初始化完成...的日志,以及用户创建成功的信息。
4. 用客户端测试连接:
mongosh "mongodb://dev:dev@localhost:27017/mydb?replicaSet=rs0&authSource=admin"
如果能正常进入MongoDB shell,说明问题解决了。
备注:内容来源于stack exchange,提问作者Magus




