私はDockerを使用しており、PHP、MySQL、Apache、およびRedisのスタックがあります。今すぐMongoDBを追加する必要があるので、最新バージョンの Dockerfile と、 MongoDB Dockerhub の docker-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で同じことを達成する方法はありますか?誰か経験や回避策はありますか?
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)
}
docker-compose
およびjs
スクリプトを使用した別のよりクリーンなソリューション。
この例では、両方のファイル(docker-compose.ymlおよびmongo-init.js)が同じフォルダーにあると想定しています。
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
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
パスワード、追加データベース(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 のソースコードを確認します。
誰かが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インスタンスが自動的に実行されます。指定されたパスワードを持つ管理データベースが作成されます。
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
また、秘密をファイルに保存することはできません。
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)