自动初始化docker中mongoDB的副本集失败

ie3xauqp  于 2023-03-22  发布在  Docker
关注(0)|答案(1)|浏览(316)

我有一个依赖于MongoDB更改流的NodeJS Express应用程序。为了使它们可用,MongoDB必须配置为作为副本集运行(即使该集中只有一个节点)。
我正在使用Windows 10 Pro。
我正在尝试将这个应用程序码头化,基于官方mongo:5镜像的MongoDB容器。
要做到这一点,我希望有一种自动化的方法将DB初始化为副本集。我发现的教程依赖于exec进入容器并从mongosh运行rs.initiate()(或类似的方法),这是我希望避免的手动工作。或者他们使用像wait-for-it.sh一样的hack作为here
我觉得一定有一个更好的解决方案,基于docs中的“初始化一个新示例”一段。
它描述了
当容器第一次启动时,它将执行在/docker-entrypoint-initdb.d中找到的扩展名为.sh.js的文件。
容器生命周期中**具体 * 什么时候发生?在容器初始化之后?还是在DB准备好之后?因为这似乎是这个初始化逻辑的完美位置,它在容器内手动执行时可以完美运行。
但是,放置

// initReplSet.js
print('Script running');
config={"_id":"rs0", "members":[{"_id":0,"host":"app-db:27017"}]};
print(JSON.stringify(rs.initiate(config)));
print('Script end');

失败,错误为{"ok":0,"errmsg":"No host described in new configuration with {version: 1, term: 0} for replica set rs0 maps to this node","code":93,"codeName":"InvalidReplicaSetConfig"},但数据库在主机名app-db下可从其他容器获得。这让我觉得这段代码运行得太早了,在所有其他初始化逻辑(网络)完成之前。
另一种方法是放置一个通过mongosh执行代码的bash脚本。

#!/bin/bash
mongosh "mongodb://app-db:27017/app_db" "initiateReplSet"

其中initiateReplSet

config={"_id":"rs0", "members":[{"_id":0,"host":"app-db:27017"}]}
rs.initiate(config)
exit

但这会使容器崩溃并显示错误

/usr/local/bin/docker-entrypoint.sh: running /docker-entrypoint-initdb.d/initiateReplSetWrapper.sh

{"t":{"$date":"2022-02-15T11:31:23.353+00:00"},"s":"I",  "c":"-",        "id":4939300, "ctx":"monitoring-keys-for-HMAC","msg":"Failed to refresh key cache","attr":{"error":"NotYetInitialized: Cannot use non-local read concern until replica set is finished initializing.","nextWakeupMillis":600}}

Warning: Could not access file: EACCES: permission denied, mkdir '/home/mongodb'

Current Mongosh Log ID: 620b8f0b04b7ad69b446768d

Connecting to: mongodb://app-db:27017/app_db?directConnection=true&appName=mongosh+1.1.9

只有第一行和最后三行似乎真正属于bash脚本,第二行不断重复。
我不确定这个错误是源于permission denied问题,还是真的无法访问数据库。

RUN mkdir -p /home/mongodb/.mongodb
RUN chown -R 777 /home/mongodb

Dockerfile中没有改善这种情况(尽管如此,同样的错误)。
你能解释一下为什么这种方法不起作用,或者如何使它起作用吗?有没有其他更好的自动化方法来初始化副本集?Docker镜像是否可以改进以允许这样的初始化逻辑?

guz6ccqo

guz6ccqo1#

我只是做了一个疯狂的实验。这意味着我只是在JS脚本中调用rs.initiate()时忽略了配置。由于某种原因,脚本然后成功运行,更改流对我的NodeJS后端可用。
我将发布在启用变更流的情况下运行MongoDB docker所需的一切:

# Dockerfile
From mongo
WORKDIR .
COPY initiateReplSet.js ./docker-entrypoint-initdb.d/
CMD ["-replSet", "rs0"]
// initiateReplSet.js
rs.initiate()

相关问题