Docker compose mongo:覆盖入口点

46scxncf  于 2023-06-21  发布在  Docker
关注(0)|答案(1)|浏览(152)

我正在尝试使用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

jljoyd4f

jljoyd4f1#

我怀疑您只是将第一个--replSet选项传递给图像的入口点脚本。我可能会将传递选项的位置从$0更改为"$@",确保传递所有选项并正确地将其引用,然后插入一个额外的参数作为(现在未使用的)$0值。

entrypoint:
  - /bin/sh
  - -c
  - |
    ...
    exec docker-entrypoint.sh "$$@"
  - entrypoint-script
command: --replSet rs0 ...

sh -c的语法是

sh -c command_string command_name argument ...

其中,command_name变为command_string中的$0值,argument s变为$1$2,依此类推。因此,为command_name参数添加一个显式值应该有助于解决语法问题。
在你的原始编队中,这被组合为:

  1. Compose解析YAML;
  2. Compose在字符串中用$替换$$;
    1.字符串格式command:被拆分为单词;
    1.覆盖的entrypoint:command:连接在一起。
    这会给你一个命令,比如
sh -c "...\nexec docker-entrypoint.sh \$0\n" --replSet rs0 ...

请注意,在这个命令中,我们只插入了一个参数$0,该位置的选项是--replSet。剩下的选项就被忽略了。
我怀疑如果你能强制Compose将command:变成一个字符串,也许是通过将它嵌入到YAML列表command: [--replSet rs0 ...]中,那么你发现的原始模式就会起作用。然后,未加引号的参数展开$0将在评估参数值之后进行字拆分。但是,在shell脚本中依赖于此通常不是一个好的做法。

相关问题