英文:
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 arguments 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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论