如何在启动时为 MongoDB 容器创建数据库?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/42912755/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to create a DB for MongoDB container on start up?
提问by ReynierPM
I am working with Docker and I have a stack with PHP, MySQL, Apache and Redis. I need to add MongoDB now so I was checking the Dockerfilefor the latest version and also the docker-entrypoint.shfile from the MongoDB Dockerhubbut I couldn't find a way to setup a default DB, admin user/password and possibly auth method for the container from a docker-compose.yml
file.
我正在使用 Docker,我有一个包含 PHP、MySQL、Apache 和 Redis 的堆栈。我需要添加的MongoDB,所以我现在是检查Dockerfile最新的版本,也将docker-entrypoint.sh从文件的MongoDB Dockerhub,但我无法找到一个方法来设置一个默认的数据库,管理员用户名/密码,并可能AUTH从docker-compose.yml
文件中获取容器的方法。
In MySQL you can setup some ENV variables as for example:
在 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}
And this will setup the DB and the user/password as the root
password.
这将设置数据库和用户/密码作为root
密码。
Is there any way to achieve the same with MongoDB? Anyone has some experience or workaround?
有什么办法可以用 MongoDB 实现相同的目标吗?任何人都有一些经验或解决方法?
回答by Matt
The official mongo
imagehas merged a PR to include the functionalityto create users and databases at startup.
该官方mongo
图片已经合并公关,包括功能,在启动时创建用户和数据库。
The database initialisation will run when there is nothing populated in the /data/db
directory.
当/data/db
目录中没有填充任何内容时,将运行数据库初始化。
Admin User Setup
管理员用户设置
The environment variables to control "root" user setup are
控制“root”用户设置的环境变量是
MONGO_INITDB_ROOT_USERNAME
MONGO_INITDB_ROOT_PASSWORD
MONGO_INITDB_ROOT_USERNAME
MONGO_INITDB_ROOT_PASSWORD
Example
例子
docker run -d \
-e MONGO_INITDB_ROOT_USERNAME=admin \
-e MONGO_INITDB_ROOT_PASSWORD=password \
mongod
You don't need to/can't use --auth
on the command line as the docker entrypoint.sh script adds this in when the environment variables exist.
您不需要/不能--auth
在命令行上使用,因为 docker entrypoint.sh 脚本会在环境变量存在时添加它。
Database Initialisation
数据库初始化
The image also provides the /docker-entrypoint-initdb.d/
path to deploy custom .js
or .sh
setup scripts that will be run once on database initialisation. .js
scripts will be run against test
by default or MONGO_INITDB_DATABASE
if defined in the environment.
该映像还提供了/docker-entrypoint-initdb.d/
部署自定义.js
或.sh
安装脚本的路径,这些脚本将在数据库初始化时运行一次。.js
脚本将在test
默认情况下运行,或者MONGO_INITDB_DATABASE
如果在环境中定义。
COPY mysetup.sh /docker-entrypoint-initdb.d/
or
或者
COPY mysetup.js /docker-entrypoint-initdb.d/
A simple initialisation javascript file that demonstrates logging and how to exit with an error (for result checking).
一个简单的初始化 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)
}
回答by Paul Wasilewski
Here another cleaner solution by using docker-compose
and a js
script.
这是使用docker-compose
和js
脚本的另一个更清洁的解决方案。
This example assumes that both files (docker-compose.yml and mongo-init.js) lay in the same folder.
此示例假设两个文件(docker-compose.yml 和 mongo-init.js)位于同一文件夹中。
docker-compose.yml
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
mongo-init.js
db.createUser(
{
user: "<user for database which shall be created>",
pwd: "<password of user>",
roles: [
{
role: "readWrite",
db: "<database to create>"
}
]
}
);
Then simply start the service by running the following docker-compose command
然后只需通过运行以下 docker-compose 命令来启动服务
docker-compose up --build -d mongodb
回答by Mateusz Stefek
Here's a working solution that creates admin-user
user with a password, additional database (test-database
), and test-user
in that database.
这是一个有效的解决方案,它admin-user
使用密码、附加数据库 ( test-database
) 并test-user
在该数据库中创建用户。
Dockerfile:
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:
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',
},
],
});
The tricky part was to understand that *.js files were run unauthenticated.
The solution authenticates the script as the admin-user
in the admin
database. MONGO_INITDB_DATABASE admin
is essential, otherwise the script would be executed against the test
db. Check the source code of docker-entrypoint.sh.
棘手的部分是要了解 *.js 文件是在未经身份验证的情况下运行的。该解决方案验证脚本作为admin-user
在admin
数据库中。MONGO_INITDB_DATABASE admin
是必不可少的,否则脚本将针对test
数据库执行。检查docker-entrypoint.sh的源代码。
回答by x-yuri
Mongo image can be affected by MONGO_INITDB_DATABASE
variable, but it won't create the database. This variable determines current database when running /docker-entrypoint-initdb.d/*
scripts. Since you can'tuse environment variables in scripts executed by Mongo, I went with a shell script:
Mongo 图像可以受MONGO_INITDB_DATABASE
变量影响,但不会创建数据库。此变量确定运行/docker-entrypoint-initdb.d/*
脚本时的当前数据库。由于您不能在 Mongo 执行的脚本中使用环境变量,我使用了一个 shell 脚本:
docker-swarm.yml
:
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
:
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
Alternatively, you can store init-mongo.sh
in configs (docker config create
) and mount it with:
或者,您可以存储init-mongo.sh
在 configs ( docker config create
) 中并使用以下命令安装它:
configs:
init-mongo.sh:
external: true
...
services:
mongo:
...
configs:
- source: init-mongo.sh
target: /docker-entrypoint-initdb.d/init-mongo.sh
And secrets can be not stored in a file.
并且机密不能存储在文件中。
回答by user2350644
In case someone is looking for how to configure MongoDB with authentication using docker-compose
, here is a sample configuration using environment variables:
如果有人正在寻找如何使用身份验证配置 MongoDB docker-compose
,这里是使用环境变量的示例配置:
version: "3.3"
services:
db:
image: mongo
environment:
- MONGO_INITDB_ROOT_USERNAME=admin
- MONGO_INITDB_ROOT_PASSWORD=<YOUR_PASSWORD>
ports:
- "27017:27017"
When running docker-compose up
your mongo instance is run automatically with auth enabled. You will have a admin database with the given password.
运行docker-compose up
mongo 实例时,会在启用身份验证的情况下自动运行。您将拥有一个带有给定密码的管理数据库。
回答by englishPete
If you are looking to remove usernames and passwords from your docker-compose.yml you can use Docker Secrets, here is how I have approached it.
如果您想从 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
I have use the file:option for my secrets however, you can also use external:and use the secrets in a swarm.
我已经为我的秘密使用了file:选项,但是你也可以使用external:并在一个群体中使用这些秘密。
The secrets are available to any script in the container at /var/run/secrets
机密可用于 /var/run/secrets 容器中的任何脚本
The Docker documentation has this to say about storing sensitive data...
Docker 文档有关于存储敏感数据的说法......
https://docs.docker.com/engine/swarm/secrets/
https://docs.docker.com/engine/swarm/secrets/
You can use secrets to manage any sensitive data which a container needs at runtime but you don't want to store in the image or in source control, such as:
您可以使用机密来管理容器在运行时需要的任何敏感数据,但您不想存储在图像或源代码控制中,例如:
Usernames and passwords TLS certificates and keys SSH keys Other important data such as the name of a database or internal server Generic strings or binary content (up to 500 kb in size)
用户名和密码 TLS 证书和密钥 SSH 密钥 其他重要数据,例如数据库或内部服务器的名称 通用字符串或二进制内容(最大 500 kb)