web-dev-qa-db-ja.com

起動時にMongoDBコンテナ用のDBを作成する方法は?

私はDockerを使用しており、PHP、MySQL、Apache、およびRedisのスタックがあります。今すぐMongoDBを追加する必要があるので、最新バージョンの Dockerfile と、 MongoDB Dockerhubdocker-entrypoint.sh ファイルをチェックしていましたしかし、docker-compose.ymlファイルからコンテナのデフォルトDB、管理者ユーザー/パスワード、およびおそらく認証方法を設定する方法を見つけることができませんでした。

MySQLでは、たとえば次のようにいくつかのENV変数を設定できます。

db:
    image: mysql:5.7
    env_file: .env
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      MYSQL_DATABASE: ${MYSQL_DATABASE}
      MYSQL_USER: ${MYSQL_USER}
      MYSQL_PASSWORD: ${MYSQL_PASSWORD}

これにより、DBとユーザー/パスワードがrootパスワードとして設定されます。

MongoDBで同じことを達成する方法はありますか?誰か経験や回避策はありますか?

30
ReynierPM

official mongo image には 機能を含めるためにPRをマージ があり、起動時にユーザーとデータベースを作成します。

/data/dbディレクトリにデータが入力されていない場合、データベースの初期化が実行されます。

管理者ユーザーの設定

「root」ユーザーのセットアップを制御する環境変数は次のとおりです。

  • MONGO_INITDB_ROOT_USERNAME
  • MONGO_INITDB_ROOT_PASSWORD

docker run -d \
  -e MONGO_INITDB_ROOT_USERNAME=admin \
  -e MONGO_INITDB_ROOT_PASSWORD=password \
  mongod

環境変数が存在するときにdocker entrypoint.shスクリプトがこれを追加するため、コマンドラインで--authを使用する必要はありません/使用できません。

データベースの初期化

このイメージは、データベースの初期化時に1回実行されるカスタム/docker-entrypoint-initdb.d/または.jsセットアップスクリプトを展開する.shパスも提供します。 .jsスクリプトは、デフォルトでtestに対して実行されるか、環境で定義されている場合はMONGO_INITDB_DATABASEに対して実行されます。

COPY mysetup.sh /docker-entrypoint-initdb.d/

または

COPY mysetup.js /docker-entrypoint-initdb.d/

ロギングおよびエラーで終了する方法を示す単純な初期化javascriptファイル(結果チェック用)。

let error = true

let res = [
  db.container.drop(),
  db.container.drop(),
  db.container.createIndex({ myfield: 1 }, { unique: true }),
  db.container.createIndex({ thatfield: 1 }),
  db.container.createIndex({ thatfield: 1 }),
  db.container.insert({ myfield: 'hello', thatfield: 'testing' }),
  db.container.insert({ myfield: 'hello2', thatfield: 'testing' }),
  db.container.insert({ myfield: 'hello3', thatfield: 'testing' }),
  db.container.insert({ myfield: 'hello3', thatfield: 'testing' }),
]

printjson(res)

if (error) {
  print('Error, exiting')
  quit(1)
}
59
Matt

docker-composeおよびjsスクリプトを使用した別のよりクリーンなソリューション。

この例では、両方のファイル(docker-compose.ymlおよびmongo-init.js)が同じフォルダーにあると想定しています。

docker-compose.yml

version: '3.7'

services:
    mongodb:
        image: mongo:latest
        container_name: mongodb
        restart: always
        environment:
            MONGO_INITDB_ROOT_USERNAME: <admin-user>
            MONGO_INITDB_ROOT_PASSWORD: <admin-password>
            MONGO_INITDB_DATABASE: <database to create>
        ports:
            - 27017:27017
        volumes:
            - ./mongo-init.js:/docker-entrypoint-initdb.d/mongo-init.js:ro

mongo-init.js

db.createUser(
        {
            user: "<user for database which shall be created>",
            pwd: "<password of user>",
            roles: [
                {
                    role: "readWrite",
                    db: "<database to create>"
                }
            ]
        }
);

次に、次のdocker-composeコマンドを実行してサービスを開始します

docker-compose up --build -d mongodb 
25
Paul Wasilewski

パスワード、追加データベース(admin-user)、およびそのデータベースにtest-dbを持つtest-userユーザーを作成する実用的なソリューションを次に示します。

Dockerfile:

FROM mongo:4.0.3

ENV MONGO_INITDB_ROOT_USERNAME admin-user
ENV MONGO_INITDB_ROOT_PASSWORD admin-password
ENV MONGO_INITDB_DATABASE admin

ADD mongo-init.js /docker-entrypoint-initdb.d/

mongo-init.js:

db.auth('admin-user', 'admin-password')

db = db.getSiblingDB('test-database')

db.createUser({
  user: 'test-user',
  pwd: 'test-password',
  roles: [
    {
      role: 'root',
      db: 'admin',
    },
  ],
});

トリッキーな部分は、*。jsファイルが認証されずに実行されたことを理解することでした。ソリューションは、adminデータベース内のadmin-userとしてスクリプトを認証します。 MONGO_INITDB_DATABASE adminは必須です。そうでない場合、スクリプトはtest dbに対して実行されます。 docker-entrypoint.sh のソースコードを確認します。

16
Mateusz Stefek

誰かがdocker-composeを使用した認証でMongoDBを構成する方法を探している場合、環境変数を使用した構成例を次に示します。

version: "3.3"

services:

  db:
      image: mongo
      environment:
        - MONGO_INITDB_ROOT_USERNAME=admin
        - MONGO_INITDB_ROOT_PASSWORD=<YOUR_PASSWORD>
      ports:
        - "27017:27017"

docker-compose upを実行すると、認証が有効な状態でmongoインスタンスが自動的に実行されます。指定されたパスワードを持つ管理データベースが作成されます。

13
user2350644

MongoイメージはMONGO_INITDB_DATABASE変数 の影響を受ける可能性がありますが、データベースは作成されません。この変数は、/docker-entrypoint-initdb.d/*scripts の実行時に現在のデータベースを決定します。 できない Mongoによって実行されるスクリプトで環境変数を使用するため、シェルスクリプトを使用しました。

docker-swarm.yml

version: '3.1'

secrets:
  mongo-root-passwd:
    file: mongo-root-passwd
  mongo-user-passwd:
    file: mongo-user-passwd

services:
  mongo:
    image: mongo:3.2
    environment:
      MONGO_INITDB_ROOT_USERNAME: $MONGO_ROOT_USER
      MONGO_INITDB_ROOT_PASSWORD_FILE: /run/secrets/mongo-root-passwd
      MONGO_INITDB_USERNAME: $MONGO_USER
      MONGO_INITDB_PASSWORD_FILE: /run/secrets/mongo-user-passwd
      MONGO_INITDB_DATABASE: $MONGO_DB
    volumes:
      - ./init-mongo.sh:/docker-entrypoint-initdb.d/init-mongo.sh
    secrets:
      - mongo-root-passwd
      - mongo-user-passwd

init-mongo.sh

mongo -- "$MONGO_INITDB_DATABASE" <<EOF
    var rootUser = '$MONGO_INITDB_ROOT_USERNAME';
    var rootPassword = '$(cat "$MONGO_INITDB_ROOT_PASSWORD_FILE")';
    var admin = db.getSiblingDB('admin');
    admin.auth(rootUser, rootPassword);

    var user = '$MONGO_INITDB_USERNAME';
    var passwd = '$(cat "$MONGO_INITDB_PASSWORD_FILE")';
    db.createUser({user: user, pwd: passwd, roles: ["readWrite"]});
EOF

または、init-mongo.shを設定に保存し(docker config create)、次のようにマウントできます:

configs:
    init-mongo.sh:
        external: true
...
services:
    mongo:
        ...
        configs:
            - source: init-mongo.sh
              target: /docker-entrypoint-initdb.d/init-mongo.sh

また、秘密をファイルに保存することはできません。

6
x-yuri

Docker-compose.ymlからユーザー名とパスワードを削除する場合は、Docker Secretsを使用できます。これがどのようにアプローチしたかです。

version: '3.6'

services:
  db:
    image: mongo:3
    container_name: mycontainer
  secrets:
    - MONGO_INITDB_ROOT_USERNAME
    - MONGO_INITDB_ROOT_PASSWORD
  environment:
    - MONGO_INITDB_ROOT_USERNAME_FILE=/var/run/secrets/MONGO_INITDB_ROOT_USERNAME
    - MONGO_INITDB_ROOT_PASSWORD_FILE=/var/run/secrets/MONGO_INITDB_ROOT_PASSWORD
secrets:
  MONGO_INITDB_ROOT_USERNAME:
    file:  secrets/${NODE_ENV}_mongo_root_username.txt
  MONGO_INITDB_ROOT_PASSWORD:
    file:  secrets/${NODE_ENV}_mongo_root_password.txt

私の秘密にはfile:オプションを使用していますが、external:群れで秘密を使用します。

シークレットは、コンテナ内の/ var/run/secretsにあるすべてのスクリプトで利用できます。

Dockerのドキュメントには、機密データの保存に関する説明があります...

https://docs.docker.com/engine/swarm/secrets/

シークレットを使用して、実行時にコンテナが必要とする機密データを管理できますが、次のような画像やソース管理に保存することは望ましくありません。

ユーザー名とパスワードTLS証明書とキーSSHキーデータベースまたは内部サーバーの名前などのその他の重要なデータ汎用文字列またはバイナリコンテンツ(サイズは最大500 kb)

3
englishPete