我有一个依赖于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镜像是否可以改进以允许这样的初始化逻辑?
1条答案
按热度按时间guz6ccqo1#
我只是做了一个疯狂的实验。这意味着我只是在JS脚本中调用
rs.initiate()
时忽略了配置。由于某种原因,脚本然后成功运行,更改流对我的NodeJS后端可用。我将发布在启用变更流的情况下运行MongoDB docker所需的一切: