如何在MogoDB 3.6的docker映像中启用更改流?

时间:2019-05-11 03:53:29

标签: mongodb docker docker-compose dockerfile changestream

我在代码中使用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)

3 个答案:

答案 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"}]})