我正在使用Docker,我有一个PHP,MySQL,Apache和Redis的堆栈。我现在需要添加MongoDB所以我正在检查Dockerfile以获取最新版本以及来自the docker-entrypoint.sh的MongoDB Dockerhub文件,但我找不到设置默认数据库的方法,管理员用户/密码以及可能来自docker-compose.yml
文件的容器的auth方法。
在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}
这会将数据库和用户/密码设置为root
密码。
有没有办法与MongoDB实现相同的目标?任何人都有一些经验或解决方法吗?
答案 0 :(得分:54)
official mongo
image有merged a PR to include the functionality在启动时创建用户和数据库。
当/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
您不需要/不能在命令行上使用--auth
,因为docker entrypoint.sh脚本会在环境变量存在时添加此内容。
该映像还提供了/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)
}
答案 1 :(得分:13)
这是使用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
答案 2 :(得分:12)
如果有人正在寻找如何使用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实例会在启用auth的情况下自动运行。您将拥有一个具有给定密码的管理数据库。
答案 3 :(得分:11)
这是一个有效的解决方案,它使用密码,附加数据库(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-user
数据库中的admin
。 MONGO_INITDB_DATABASE admin
是必不可少的,否则脚本将针对test
数据库执行。检查docker-entrypoint.sh的源代码。
答案 4 :(得分:4)
给出此.env
文件:
DB_NAME=foo
DB_USER=bar
DB_PASSWORD=baz
这个mongo-init.sh
文件:
mongo --eval "db.auth('$MONGO_INITDB_ROOT_USERNAME', '$MONGO_INITDB_ROOT_PASSWORD'); db = db.getSiblingDB('$DB_NAME'); db.createUser({ user: '$DB_USER', pwd: '$DB_PASSWORD', roles: [{ role: 'readWrite', db: '$DB_NAME' }] });"
此docker-compose.yml
将创建admin数据库和admin用户,以admin用户身份进行身份验证,然后创建真实数据库并添加真实用户:
version: '3'
services:
# app:
# build: .
# env_file: .env
# environment:
# DB_HOST: 'mongodb://mongodb'
mongodb:
image: mongo:4
environment:
MONGO_INITDB_ROOT_USERNAME: admin-user
MONGO_INITDB_ROOT_PASSWORD: admin-password
DB_NAME: $DB_NAME
DB_USER: $DB_USER
DB_PASSWORD: $DB_PASSWORD
ports:
- 27017:27017
volumes:
- db-data:/data/db
- ./mongo-init.sh:/docker-entrypoint-initdb.d/mongo-init.sh
volumes:
db-data:
答案 5 :(得分:3)
Mongo图像可能受MONGO_INITDB_DATABASE
variable的影响,但不会创建数据库。运行/docker-entrypoint-initdb.d/*
scripts时,此变量确定当前数据库。由于您can't在Mongo执行的脚本中使用环境变量,因此我使用了shell脚本:
docker-cloud.yml
:
version: '3.1'
secrets:
mongo-passwd:
file: mongo-passwd
services:
mongo:
image: mongo:3.2
environment:
MONGO_DB: ${MONGO_DB}
MONGO_INITDB_ROOT_USERNAME: ${MONGO_USER}
MONGO_INITDB_ROOT_PASSWORD_FILE: /run/secrets/mongo-passwd
volumes:
- ./init-mongo.sh:/docker-entrypoint-initdb.d/init-mongo.sh
secrets:
- mongo-passwd
init-mongo.sh
:
mongo -- "$MONGO_DB" <<EOF
var user = '$MONGO_INITDB_ROOT_USERNAME';
var passwd = '$MONGO_INITDB_ROOT_PASSWORD';
var admin = db.getSiblingDB('admin');
admin.auth(user, passwd);
db.createUser({user: user, pwd: passwd, roles: ["readWrite"]});
EOF
答案 6 :(得分:2)
这对我有用:
docker-compose.yaml
version: "3.8"
services:
mongodb:
image: mongo:3.6
restart: always
environment:
- MONGO_INITDB_ROOT_USERNAME=root
- MONGO_INITDB_ROOT_PASSWORD=hello
volumes:
- ./mongo-init/:/docker-entrypoint-initdb.d/:ro
ports:
- 27017:27017
- 9229:9229
mongo-express:
image: mongo-express
restart: always
ports:
- 8111:8081
environment:
- ME_CONFIG_MONGODB_SERVER=mongodb
- ME_CONFIG_MONGODB_ADMINUSERNAME=root
- ME_CONFIG_MONGODB_ADMINPASSWORD=hello
./mongo-init/init.js
conn = new Mongo();
db = conn.getDB("MyDatabaseName");
db.myCollectionName.createIndex({ "address.zip": 1 }, { unique: false });
db.myCollectionName.insert({ "address": { "city": "Paris", "zip": "123" }, "name": "Mike", "phone": "1234" });
db.myCollectionName.insert({ "address": { "city": "Marsel", "zip": "321" }, "name": "Helga", "phone": "4321" });
通过 http://localhost:8111/ 查看仪表板:
答案 7 :(得分:1)
如果您希望从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)
答案 8 :(得分:1)
我的回答是基于@x-yuri 提供的;但我的情况有点不同。我想要一个包含脚本的图像,而不是绑定而不需要绑定安装它。
mongo-init.sh
-- 不知道是否需要,但我也跑了 chmod +x mongo-init.sh
:
#!/bin/bash
# https://stackoverflow.com/a/53522699
# https://stackoverflow.com/a/37811764
mongo -- "$MONGO_INITDB_DATABASE" <<EOF
var rootUser = '$MONGO_INITDB_ROOT_USERNAME';
var rootPassword = '$MONGO_INITDB_ROOT_PASSWORD';
var user = '$MONGO_INITDB_USERNAME';
var passwd = '$MONGO_INITDB_PASSWORD';
var admin = db.getSiblingDB('admin');
admin.auth(rootUser, rootPassword);
db.createUser({
user: user,
pwd: passwd,
roles: [
{
role: "root",
db: "admin"
}
]
});
EOF
Dockerfile
:
FROM mongo:3.6
COPY mongo-init.sh /docker-entrypoint-initdb.d/mongo-init.sh
CMD [ "/docker-entrypoint-initdb.d/mongo-init.sh" ]
docker-compose.yml
:
version: '3'
services:
mongodb:
build: .
container_name: mongodb-test
environment:
- MONGO_INITDB_ROOT_USERNAME=root
- MONGO_INITDB_ROOT_PASSWORD=example
- MONGO_INITDB_USERNAME=myproject
- MONGO_INITDB_PASSWORD=myproject
- MONGO_INITDB_DATABASE=myproject
myproject:
image: myuser/myimage
restart: on-failure
container_name: myproject
environment:
- DB_URI=mongodb
- DB_HOST=mongodb-test
- DB_NAME=myproject
- DB_USERNAME=myproject
- DB_PASSWORD=myproject
- DB_OPTIONS=
- DB_PORT=27017
ports:
- "80:80"
在那之后,我继续将此 Dockefile 发布为图像以用于其他项目。
注意:没有添加 CMD
它 mongo 抛出:未绑定变量错误
答案 9 :(得分:1)
如果您正在使用 docker-compose 并在创建卷后尝试运行这些建议中的任何一个,您可能需要删除该卷,因为如果该卷已经存在,init 脚本将不会运行。
要查看是否是这种情况,请尝试运行:-
docker volume ls
如果您的 mongo 数据在那里,您应该在卷名中看到它,例如:-
<db>_<volume>
如果卷类似于 db_volume,您将需要运行:-
docker volume rm db_volume
您可能需要将容器放入垃圾箱才能使其正常工作。
答案 10 :(得分:0)
在没有 root 访问权限的情况下在 MongoDB docker 容器中创建多个数据库和用户的步骤。
docker-compose down
命令,如果您有多个文件,则为 'docker-compose -f docker-compose.yml -f docker-compose.dev.yml <...>'
。'docker volume ls'
。如果有类似于 <projectfolder>_mongodb--vol
的内容,请通过应用将其删除
docker volume rm <projectfolder>_mongodb--vol
.js
或 .sh
mongo 数据库 init scripts 设置文件夹。例如,mongo-init/db_1.js
:
conn = new Mongo();
db = conn.getDB("db_1")
db.createUser(
{
user: "db_1_service_user",
pwd: "<password>",
roles: [
{
role: "readWrite",
db: "db_1"
}
]
}
);
对 mongo-init/db_2.js
文件重复该过程。 conn.getDB() 创建数据库,db.createUser() 创建用户并将其分配给数据库。./mongo-init/
本地文件夹到远程 /docker-entrypoint-initdb.d/
的挂载绑定:
version: "3.8"
services:
my-service_1:
depends_on:
- mongodb
my-service_2:
depends_on:
- mongodb
mongodb:
image: mongo:4.4-bionic
ports:
- "27017:27017"
volumes:
- mongodb--vol:/data/db
- ./mongo-init/:/docker-entrypoint-initdb.d/:ro
healthcheck:
test: "echo 'db.runCommand(\"ping\").ok'"
interval: 5s
timeout: 5s
retries: 3
# in-service volumes are very slow in MacOS and Windows,
# so using fast shared volumes for large storage
volumes:
mongodb--vol:
mongodb://db_1_service_user:<password>@mongodb:27017/db_1
mongodb://db_2_service_user:<password>@mongodb:27017/db_2
答案 11 :(得分:0)
只是对这里几个答案的快速补充 - 这一切都很棒,它确实为我节省了很多时间来解决问题! 如果您要创建的用户需要附加到特定数据库,我会添加一些代码
最重要的是,您需要登录到您的管理员库才能创建新用户。因此,当所有 docker-compose.yml 出现在提要上时,您的 mongo-init.js 文件将如下所示:
db = db.getSiblingDB('admin');
// move to the admin db - always created in Mongo
db.auth("rootUser", "rootPassword");
// log as root admin if you decided to authenticate in your docker-compose file...
db = db.getSiblingDB('DB_test');
// create and move to your new database
db.createUser({
'user': "dbUser",
'pwd': "dbPwd",
'roles': [{
'role': 'dbOwner',
'db': 'DB_test'}]});
// user created
db.createCollection('collection_test');
// add new collection
如果这可以帮助某人,我很高兴 - 欢呼,