Docker配置MongoDB单节点副本集如何自动执行rs.initiate()命令
解决方案
你之前的尝试行不通,是因为官方mongo镜像的command配置的参数默认是传给mongod主进程的,mongod本身不识别mongosh、rs.initiate()这类参数,所以启动会失败。
官方Mongo镜像内置了初始化逻辑,只有第一次启动、数据目录为空的时候,会自动执行/docker-entrypoint-initdb.d/目录下的.js、.sh脚本,我们可以用这个机制实现自动初始化副本集,这是最稳定的方案。
方案1(推荐:独立初始化脚本,易维护)
步骤1:新建初始化脚本
在docker-compose.yml同级目录下新建init-replica.js文件,内容如下:
rs.initiate({ _id: "rs0", members: [ { _id: 0, host: "mongodb:27017" } ] })
这里显式指定host为容器名mongodb,避免副本集默认绑定localhost导致其他容器无法访问的问题
步骤2:修改docker-compose.yml配置
调整你的mongodb服务配置,增加脚本挂载:
mongodb: image: mongo:5.0 container_name: mongodb command: ["--replSet", "rs0", "--bind_ip_all"] networks: - dev ports: - 27017:27017 volumes: - ${HOME}/mongodb:/data/db # 新增:把初始化脚本挂载到镜像指定的初始化目录,只读即可 - ./init-replica.js:/docker-entrypoint-initdb.d/init-replica.js:ro
注意事项
如果之前已经启动过mongodb,${HOME}/mongodb目录已经有数据,初始化脚本不会自动执行,需要先清空该目录再启动容器。
方案2(无额外文件,单command实现)
如果你不想额外创建脚本文件,也可以直接用shell包装启动逻辑,修改command配置如下即可:
mongodb: image: mongo:5.0 container_name: mongodb # 覆盖默认启动逻辑,先启动mongod,等就绪后执行初始化,再挂起主进程 command: > bash -c " mongod --replSet rs0 --bind_ip_all & MONGOD_PID=\$! # 等待mongod启动就绪 until mongosh --eval 'db.adminCommand(\"ping\")' > /dev/null 2>&1; do sleep 1; done # 执行副本集初始化 mongosh --eval 'rs.initiate({_id: \"rs0\", members: [{_id: 0, host: \"mongodb:27017\"}]})' # 挂起mongod主进程,避免容器退出 wait \$MONGOD_PID " networks: - dev ports: - 27017:27017 volumes: - ${HOME}/mongodb:/data/db
内容的提问来源于stack exchange,提问作者ATHER
相关产品推荐
相关产品推荐

