如何在Docker Compose后运行Mongo shell命令?

4
我将开始这个 MongoDB 副本集:
version: "3"

services:
  mongo1:
    image: mongo
    ports:
      - 27017:27017
    command: mongod --replSet rs0
  mongo2:
    image: mongo
    ports:
      - 27018:27017
    command: mongod --replSet rs0
  mongo3:
    image: mongo
    ports:
      - 27019:27017
    command: mongod --replSet rs0

等待它们出现,然后通过终端访问Mongo shell:

docker exec -it mongo1 mongo

然后在Mongo shell中执行以下命令:

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

Mongo还允许使用mongo --eval "rs.initiate(..)",这可能会使事情更加容易。

我的问题是,在mongo1、mongo2和mongo3启动后,我该如何运行此命令?


当你运行这个程序时会发生什么?我想你可以设置一个容器名称来使它更容易一些吗? - Robert Seaman
如果我手动这样做,它是有效的,但我希望它能够自动化并部署到云端。 - atkayla
2个回答

3

您可以这样做,最近我不得不运行mongo --repair 然后运行MongoDB本身,等MongoDB启动后,我需要将我的用户添加到数据库中,您可以轻松更改内容以在三个 MongoDB全部启动后再运行命令。

可能的docker-compose.yml:

version: "2"
services:
  mongo:
    container_name: mongo
    restart: on-failure:10
    image: mongo
    environment:
      - MONGO_INITDB_ROOT_USERNAME=<user>
      - MONGO_INITDB_ROOT_PASSWORD=<pass>
      - MONGO_INITDB_DATABASE=db
    volumes:
      - ./data:/data/db
    ports:
      - "27017:27017"
    command: bash -c "mongod --repair && mongod"

  mongoClient:
    image: mongo
    container_name: mongoClient
    links:
      - mongo
    volumes:
      - ./deployment_scripts:/deployment_scripts
    command: 
      - /deployment_scripts/add_user.sh
    depends_on:
      - mongo

  app:
    container_name: app
    restart: always
    build: .
    volumes:
      - .:/usr/src/app
    ports:
      - "3000:3000"
    depends_on:
      - mongoClient
    links:
      - mongo

我的/deployment_scripts/add_user.sh脚本等待MongoDB启动:
until mongo --host mongo --eval "print(\"waited for connection\")"
do
    sleep 1
done

// you can add more MongoDB waits here

echo "Adding user to MongoDB..."
mongo --host mongo --eval "db.createUser({ user: \"<user>\", pwd: \"<pass>\", roles: [ { role: \"root\", db: \"admin\" } ] });"
echo "User added."

请注意,您可以通过将--host mongo替换为--host mongo1--host mongo2--host mongo3来访问您的三个MongoDB。在脚本中的两个eval命令中都会使用此选项。
感谢这个SO答案https://dev59.com/b2Up5IYBdhLWcg3wNFar#45060399,我使用了其中的代码(until mongo ...)。

-1

我假设您正在使用官方Mongo镜像,该镜像已配置为:

ENTRYPOINT ["docker-entrypoint.sh"]
CMD ["mongod"]

如果您检查docker-entrypoint.sh,您会注意到可以通过覆盖CMD来运行任何命令。
因此,您可以为每个mongo容器执行以下操作。
$ docker run -d mongo
9bf0473d491a2d7ae821bcf10ed08cd49678d28e46344589622bd9440a6aca65

$ docker ps -q
9bf0473d491a

$ docker exec -ti 9bf0473d491a mongo --eval "rs.initiate(.....)"
MongoDB shell version v3.6.5
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.6.5
{
    "ok" : 0,
    "errmsg" : "This node was not started with the replSet option",
    "code" : 76,
    "codeName" : "NoReplicationEnabled"
}

请注意,errmsg只是因为在我的示例中rs.initiate()为空,如果您使用正确的配置,它将正常工作。

你好。非常抱歉问这个愚蠢的问题,但我应该编辑什么?您是指拉取图像,编辑图像,然后提交我的修改后的图像吗?我希望能在我的docker-compose中轻松地插入一个简单的命令。此外,我只想在所有副本启动后执行一次rs.initiate(...),而不是每个副本都执行。 - atkayla
@kaya 我认为仅使用docker-compose无法以那种方式配置mongo镜像。我建议在部署后使用docker exec进行配置。我的猜测是,仅使用docker-compose配置动态添加MongoDB副本集需要进行一些广泛的工作。 - Robert Seaman
@kayla,请编辑 rs.initiate(...) 并将 ... 替换为您自己的 JSON 配置以初始化 RS。 - Koe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接