英文:
Docker compose mongo: Overriding entrypoint
问题
我正在尝试使用Docker Compose设置带有副本集的MongoDB:
services:
mongo1:
image: mongo:6
container_name: mongo-rs-primary
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: password
MONGO_INITDB_DATABASE: admin
volumes:
- ./_docker/volumes/mongo1:/data/db
- ./_docker/mongo-rs-key:/data/mongo-rs-key
ports:
- 27017:27017
entrypoint:
- bash
- -c
- |
chmod 400 /data/mongo-rs-key
chown 999:999 /data/mongo-rs-key
exec docker-entrypoint.sh $$0
command: --replSet rs0 --keyFile /data/mongo-rs-key --port 27017
mongo2:
image: mongo:6
container_name: mongo-rs-replica1
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: password
MONGO_INITDB_DATABASE: admin
volumes:
- ./_docker/volumes/mongo2:/data/db
- ./_docker/mongo-rs-key:/data/mongo-rs-key
ports:
- 27018:27018
entrypoint:
- bash
- -c
- |
chmod 400 /data/mongo-rs-key
chown 999:999 /data/mongo-rs-key
exec docker-entrypoint.sh $$0
command: --replSet rs0 --keyFile /data/mongo-rs-key --port 27018
mongo3:
image: mongo:6
container_name: mongo-rs-replica2
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: password
MONGO_INITDB_DATABASE: admin
volumes:
- ./_docker/volumes/mongo3:/data/db
- ./_docker/mongo-rs-key:/data/mongo-rs-key
ports:
- 27019:27019
entrypoint:
- bash
- -c
- |
chmod 400 /data/mongo-rs-key
chown 999:999 /data/mongo-rs-key
exec docker-entrypoint.sh $$0
command: --replSet rs0 --keyFile /data/mongo-rs-key --port 27019
请注意,我需要覆盖安全密钥文件的所有权,我在网上找到了这种方法,但奇怪的是现在我的副本集名称是--auth
而不是rs0
?我怀疑是因为exec docker-entrypoint.sh $$0
,但是出了什么问题?我从某个地方复制了它,似乎在--replSet
中使用了--auth
而不是rs0
。
英文:
I am trying to setup a MongoDB with replicaset with Docker Compose:
services:
mongo1:
image: mongo:6
container_name: mongo-rs-primary
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: password
MONGO_INITDB_DATABASE: admin
volumes:
- ./_docker/volumes/mongo1:/data/db
- ./_docker/mongo-rs-key:/data/mongo-rs-key
ports:
- 27017:27017
entrypoint:
- bash
- -c
- |
chmod 400 /data/mongo-rs-key
chown 999:999 /data/mongo-rs-key
exec docker-entrypoint.sh $$0
command: --replSet rs0 --keyFile /data/mongo-rs-key --port 27017
mongo2:
image: mongo:6
container_name: mongo-rs-replica1
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: password
MONGO_INITDB_DATABASE: admin
volumes:
- ./_docker/volumes/mongo2:/data/db
- ./_docker/mongo-rs-key:/data/mongo-rs-key
ports:
- 27018:27018
entrypoint:
- bash
- -c
- |
chmod 400 /data/mongo-rs-key
chown 999:999 /data/mongo-rs-key
exec docker-entrypoint.sh $$0
command: --replSet rs0 --keyFile /data/mongo-rs-key --port 27018
mongo3:
image: mongo:6
container_name: mongo-rs-replica2
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: password
MONGO_INITDB_DATABASE: admin
volumes:
- ./_docker/volumes/mongo3:/data/db
- ./_docker/mongo-rs-key:/data/mongo-rs-key
ports:
- 27019:27019
entrypoint:
- bash
- -c
- |
chmod 400 /data/mongo-rs-key
chown 999:999 /data/mongo-rs-key
exec docker-entrypoint.sh $$0
command: --replSet rs0 --keyFile /data/mongo-rs-key --port 27019
Note that I needed to override the ownership of the security key file and I found online this is one way to do it, however, the weird thing is now my replica set name is --auth
and not rs0
? I suspect its because of exec docker-entrypoint.sh $$0
but whats wrong? I copied that from somewhere, seems like its using --auth
in --replSet
instead of rs0
答案1
得分: 2
我怀疑你只传递了第一个 --replSet
选项给镜像的入口脚本。我可能会改变你传递选项的方式,从 $0
改为 "$@"
,确保传递所有选项并正确引用它,然后插入一个额外的参数作为(现在未使用的)$0
值。
entrypoint:
- /bin/sh
- -c
- |
...
exec docker-entrypoint.sh "$$@"
- entrypoint-script
command: --replSet rs0 ...
sh -c command_string command_name argument ...
其中 command_name
变成了 command_string
内部的 $0
值,而 argument
变成了 $1
、$2
等等。因此,为 command_name
参数添加一个明确的值应该有助于解决语法问题。
在你的原始配置中,这被组合成:
- Compose 解析 YAML;
- Compose 在字符串内部用
$
替换$$
; - 字符串格式的
command:
被拆分成单词; - 被覆盖的
entrypoint:
和command:
被连接在一起。
这会得到如下命令:
sh -c "...\nexec docker-entrypoint.sh $0\n" --replSet rs0 ...
请注意,在此命令中,我们只插入了单一的参数 $0
,而该位置的选项是 --replSet
。其余选项将被忽略。
我怀疑如果你能强制 Compose 将 command:
转换为一个单一字符串,可能通过将其嵌入到 YAML 列表中 command: [--replSet rs0 ...]
。然后,未引用的参数展开 $0
将在评估参数值后执行单词拆分。尽管如此,在 shell 脚本中依赖这种行为通常不是一个好做法。
英文:
I suspect you're only passing the first --replSet
option to the image's entrypoint script. I might change the place you pass on the option from $0
to "$@"
, making sure to pass all the options and to correctly quote it, and then insert an extra argument to be the (now unused) $0
value.
entrypoint:
- /bin/sh
- -c
- |
...
exec docker-entrypoint.sh "$$@"
- entrypoint-script
command: --replSet rs0 ...
The syntax of sh -c
is
sh -c command_string command_name argument ...
where command_name
becomes the $0
value inside command_string
, and the argument
s become $1
, $2
, and so on. So adding an explicit value for the command_name
argument should help resolve the syntax.
In your original formation, this gets put together as:
- Compose parses the YAML;
- Compose replaces
$$
with$
inside the string; - The string-format
command:
is split into words; - The overridden
entrypoint:
andcommand:
are concatenated together.
This gives you a command like
sh -c "...\nexec docker-entrypoint.sh $0\n" --replSet rs0 ...
Notice in this command we're only inserting the single parameter $0
, and the option in that position is --replSet
. The remaining options just get ignored.
I suspect the original pattern you had found would work if you could force Compose to make the command:
into a single string, maybe by embedding it into a YAML list command: [--replSet rs0 ...]
. Then the unquoted parameter expansion $0
would do word splitting after evaluating the parameter value. It's usually not a good practice in shell scripts to rely on this, though.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论