我在代码中使用MongoDB更改流,并且需要创建一个启用了更改流的MongoDB docker映像。 问题在于mongod应该首先使用默认设置启动,以允许创建用户,文档等。 然后应停止mongod。然后,应将副本集添加到mongod.conf以启用更改流:
# mongod.conf
replication:
replSetName: rs0
oplogSizeMB: 100
此后,应重新启动mongod并由MongoDB shell初始化副本集:
rs.slaveOk()
rs.initiate()
rs.initiate({_id:"rs0", members: [{"_id":1, "host":"127.0.0.1:27017"}]})
MogodDB 3.6 base image提供了初始化功能。 您知道如何启动mongod,初始化DB,然后停止它并重新配置吗?
UPD: 我需要初始化数据库,然后添加副本集。 因此,我需要使用默认的mongod.conf运行nongod,创建用户和集合,然后使用启用了副本集的另一个mongod,conf重新启动mongod。我不能用官方的MongoDB映像来做到这一点。我已经在Ubuntu映像上安装了MongoDB 3.6.12。在其bash shell中手动运行设置命令后,我的MongoDB容器运行良好,但是相同的指令在Dockerfile中不起作用 这是命令
RUN mongod --fork --config /etc/mongod.conf \
&& mongo < /opt/init_mongodb.js \
&& mongod --shutdown --dbpath /var/lib/mongodb \
&& cp /etc/mongod.conf /etc/mongod.conf.orig \
&& mongod --fork --config /opt/mongod.conf \
&& mongo -u "root" -p "root" --authenticationDatabase "admin" < /opt/reconfig_mongodb.js \
从Dockerfile运行此命令时,出现以下错误
> backend@1.0.0 start /usr/src/app
> npm run babelserver
> backend@1.0.0 babelserver /usr/src/app
> babel-node --presets es2015 index.js
(node:41) UnhandledPromiseRejectionWarning: MongoError: not master and slaveOk=false
at queryCallback (/usr/src/app/node_modules/mongodb-core/lib/cursor.js:248:25)
at /usr/src/app/node_modules/mongodb-core/lib/connection/pool.js:532:18
at processTicksAndRejections (internal/process/task_queues.js:82:9)
(node:41) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
答案 0 :(得分:2)
我认为这不是设置副本集的干净方法。确实应该更简单。
您可以只运行一个附加的“ helper”容器(而不是在后台模式下运行成员之一,设置副本集,保存配置文件,关闭进程以及最后从保存的配置文件开始), mongodb映像),其唯一目的是在不充当成员的情况下设置mongodb副本集。
可以执行以下操作:
docker-compose.yaml
version: '3'
services:
mongodb-rs0-1:
image: ${your_image}
ports: [27018:27018]
environment:
- PORT=27018
- MONGO_RS=rs0/mongodb-rs0-1:27018,mongodb-rs0-2:27019,mongodb-rs0-3:27020
volumes:
- ./db/rs0-1:/data/db
mongodb-rs0-2:
image: ${your_image}
ports: [27019:27019]
environment:
- PORT=27019
- MONGO_RS=rs0/mongodb-rs0-1:27018,mongodb-rs0-2:27019,mongodb-rs0-3:27020
volumes:
- ./db/rs0-2:/data/db
mongodb-rs0-3:
image: ${your_image}
ports: [27020:27020]
environment:
- PORT=27020
- MONGO_RS=rs0/mongodb-rs0-1:27018,mongodb-rs0-2:27019,mongodb-rs0-3:27020
volumes:
- ./db/rs0-3:/data/db
mongodb-replicator:
image: ${your_image}
environment:
- PRIMARY=mongodb-rs0-1:27018
depends_on:
- mongodb-rs0-1
- mongodb-rs0-2
- mongodb-rs0-3
networks:
default:
external:
name: mongo
和 container_start.sh 中:
#!/bin/sh
if [ -z "$PRIMARY" ]; then
# Member container
docker-entrypoint.sh --replSet rs0 --smallfiles --oplogSize 128 --port "${PORT-27017}"
else
# Replicator container
until mongo "$PRIMARY" /app/replicaset-setup.js; do
sleep 10
done
fi
答案 1 :(得分:1)
即使以为我花了好几个小时才弄清楚,设置启用复制的dockerized mongodb实例(允许使用变更流)实际上很容易
将它们都放在同一个文件夹中
Dockerfile
FROM mongo:4.4
ADD ./init_replicaset.js /docker-entrypoint-initdb.d/init_replicaset.js
CMD ["mongod", "--replSet", "rs0", "--bind_ip_all"]
init_replicaset.js
rs.initiate({'_id':'rs0', members: [{'_id':1, 'host':'127.0.0.1:27017'}]});
注意:初始化mongo实例时,/docker-entrypoint-initdb.d
目录中的所有.js / .sh文件都会自动运行。这就是为什么这样的原因。
在同一文件夹中,运行以下命令:
docker build . -t mongo_repl
docker run -i -p 27017:27017 mongo_repl
就是这样!现在,您应该有一个运行中的mongodb实例,该实例具有复制功能。
答案 2 :(得分:0)
通过在容器启动时初始化副本集来解决。 该脚本在docker文件中设置为ENTRYPOINT
#!/bin/sh
# start mongod, initialize replica set
mongod --fork --config /opt/mongod.conf
mongo --quiet < /opt/replica.js
# restart mongod
mongod --shutdown --dbpath /var/lib/mongodb
mongod --config /opt/mongod.conf
replica.js
rs.slaveOk()
rs.initiate()
rs.initiate({_id:"rs0", members: [{"_id":1, "host":"127.0.0.1:27017"}]})