排查顺序

1. 首先要检查用户名密码正确性,还有因为Windows会开机自启一个MongoDB的服务,如果和Docker的服务在同一端口,会连接到Windows的服务,也会导致Authentication failed错误,如果要连接Docker的服务一定要关掉

2. 数据卷已存在,初始化脚本不会再次执行

MongoDB 官方镜像只有在 /data/db 目录为空时才会执行初始化脚本(包括创建 root 用户)。如果你之前已经启动过容器,mongo1_datamongo2_datamongo3_data 这些卷已经存在,即使你改了环境变量,也不会重新创建 admin 用户

解决方法:

  • 清理所有 MongoDB 数据卷(会清空所有数据)
docker-compose down -v
docker-compose up -d

3. 是否设置了副本集

如果设置了副本集,并且设置了MONGO_INITDB_ROOT_USERNAME 和 MONGO_INITDB_ROOT_PASSWORD,可能是副本集未初始化,导致无法写入用户。

由于MongoDB 容器启动时已经启用了认证(设置了 MONGO_INITDB_ROOT_USERNAME 和 MONGO_INITDB_ROOT_PASSWORD),导致副本集初始化时必须认证,但此时还没有用户,陷入死循环

出现没有自动初始化副本集(replica set)的情况,是因为MongoDB 官方镜像不会自动帮你执行 rs.initiate(),即使你配置了 --replSet 参数。
官方镜像只会自动创建用户(如果数据卷为空),但不会自动初始化副本集,这需要你手动在 mongo shell 里执行一次


原因总结

  • --replSet 只是让 mongod 进程以副本集模式启动,但不会自动初始化副本集配置。
  • 官方镜像没有内置自动执行 rs.initiate() 的机制。
  • 所以你每次新部署副本集,都需要手动初始化

如果副本集没有初始化,所有节点都是 SECONDARY,也无法创建用户。你需要先在主容器内执行副本集初始化(只需一次):

下面的例子,我有三个节点mongo1 mongo2 mongo3replSet参数值rs0,根据自己情况酌情修改

进入主容器

docker exec -it mongo1 mongosh

初始化

rs.initiate({
  _id: "rs0",
  members: [
    { _id: 0, host: "mongo1:27017" },
    { _id: 1, host: "mongo2:27017" },
    { _id: 2, host: "mongo3:27017" }
  ]
})

检查副本集状态

rs.status()

你应该能看到一个节点变成 PRIMARY,其余为 SECONDARY,这可能需要一些时间。

当副本集初始化完成并竞选了主节点后,进入主节点添加用户(如mongo1为PRIMARY

docker exec -it mongo1 mongosh
use admin
db.createUser({user: "用户名", pwd: "密码", roles: ["root"]})

验证用户

db.auth('用户名', '密码')

显示{ ok: 1 }则添加成功

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐