如何使用 docker-compose 在 mongodb 中创建用户
How to create user in mongodb with docker-compose
我正在尝试创建某种类型的脚本,该脚本将使用 mongodb 创建一个 docker 并自动创建一个用户。
我通常可以使用 docker-compose 管理我的 docker 图片,但这次,我不知道该怎么做。
基本上,这是我必须做的:
- clean/destroy 容器 (
docker-compose down
)
- 使用 mongodb 创建一个 docker 容器并启动它(没有
--auth parameter
)
- 执行包含
db.createUser()
的java脚本
- 停止容器
- 使用
--auth
参数重新启动同一个容器,以允许使用在 java 脚本 中创建的用户登录
我找不到如何使用 docker-compose 正确地做到这一点,因为当它启动时,我必须给它命令 --auth。如果这样做,我将无法执行我的 java 脚本来添加我的用户。 MongoDB 如果没有用户且未提供 --auth 参数,则允许在不登录的情况下创建用户。
我想自动执行,我不想手动执行某些命令。目标是拥有一个可以在每次集成测试之前执行的脚本,以从干净的数据库开始。
这是我的项目:
integration-test/src/test/resources/scripts/docker-compose.yml
mongodb:
container_name: mongo
image: mongo
ports:
- "27017:27017"
volumes:
- .:/setup
command: --auth
integration-test/src/test/resources/scripts/docker-init.sh
docker-compose down
docker-compose up -d
sleep 1
docker exec mongo bash -c "mongo myDatabase /setup/mongodb-setup.js"
integration-test/src/test/resources/scripts/mongodb-setup.js
db.createUser(
{
user: "myUser",
pwd: "myPassword",
roles: [
{ role: "readWrite", db: "myDatabase" }
]
})
找到一种使用新参数重新启动容器的方法(在本例中为 --auth
)会有所帮助,但我找不到该怎么做(docker 启动不带参数).
知道我应该怎么做吗?
如果没有,我仍然可以使用一些 Java 代码或其他东西从我的数据库中删除所有内容,但我想要一个完整的 mongodb docker 使用脚本创建的设置。
编辑: tutumcloud 存储库已弃用且不再维护,请参阅其他答案
我建议你使用环境变量来设置mongo用户、数据库和密码。 tutum
(拥有者Docker)发布了一张非常好的图片
https://github.com/tutumcloud/mongodb
docker run -d -p 27017:27017 -p 28017:28017 -e MONGODB_USER="user" -e MONGODB_DATABASE="mydatabase" -e MONGODB_PASS="mypass" tutum/mongodb
您可以将这些变量转换为 docker-compose 环境变量。您不必对其进行硬编码。
environment:
MONGODB_USER: "${db_user_env}"
MONGODB_DATABASE: "${dbname_env}"
MONGODB_PASS: "${db_pass}"
此配置将从您会话的环境变量中读取。
向 mongo 命令添加 --noauth 选项
从我的 docker-compose.yml 文件中提取
mongors:
image: mongo:latest
command: mongod --noprealloc --smallfiles --replSet mongors2 --dbpath /data/db --nojournal --oplogSize 16 --noauth
environment:
TERM: xterm
volumes:
- ./data/mongors:/data/db
阅读官方mongo docker page后,我发现即使使用了 auth 选项,您也可以一次性创建一个管理员用户。这没有很好的记录,但它确实有效(希望它不是一个功能)。
因此,您可以一直使用 auth 选项。
我创建了一个 github 存储库,其中包含包含要使用的命令的脚本。 运行 最重要的命令行是:
docker exec db_mongodb mongo admin /setup/create-admin.js
docker exec db_mongodb mongo admin /setup/create-user.js -u admin -p admin --authenticationDatabase admin
第一行将创建管理员用户(并且 mongo 即使使用 auth 选项也不会抱怨)。第二行将创建您的 "normal" 用户,使用第一行的管理员权限。
我就是这样做的,我的要求是与 mongodb 一起启动一些容器,其他容器希望用户在出现时在场,这对我有用。好的部分是,mongoClientTemp 在命令执行后退出,因此容器不会停留。
version: '2'
services:
mongo:
image: mongo:latest
container_name: mongo
ports:
- "27017:27017"
volumes:
- /app/hdp/mongo/data:/data/db
mongoClientTemp:
image: mongo:latest
container_name: mongoClientTemp
links:
- mongo:mongo
command: mongo --host mongo --eval "db.getSiblingDB('dashboard').createUser({user:'db', pwd:'dbpass', roles:[{role:'readWrite',db:'dashboard'}]});"
depends_on:
- mongo
another-container:
image: another-image:v01
container_name: another-container
ports:
- "8080:8080"
volumes:
- ./logs:/app/logs
environment:
- MONGODB_HOST=mongo
- MONGODB_PORT=27017
links:
- mongo:mongo
depends_on:
- mongoClientTemp
官方 mongo 镜像现在支持以下环境变量,可以在 docker-compose 中使用,如下所示:
environment:
- MONGO_INITDB_ROOT_USERNAME=user
- MONGO_INITDB_ROOT_PASSWORD=password
- MONGO_INITDB_DATABASE=test
更多解释请见:
文件:docker-compose.yaml
mongo:
image: mongo:latest
volumes_from:
- data
ports:
- "27017:27017"
command: --auth
container_name: "db_mongodb"
data:
image: mongo:latest
volumes:
- /var/lib/mongo
- ./setup:/setup
command: "true"
container_name: "db_mongodb_data"
文件:.buildMongo.sh
#!/bin/sh
docker-compose down
docker-compose up -d
sleep 1
docker exec db_mongodb mongo admin /setup/create-admin.js
docker exec db_mongodb mongo myDb /setup/create-user.js -u admin -p admin --authenticationDatabase admin
create-admin.js 和 create-user.js 文件是您使用 mongo shell 使用的命令。因此,它们必须易于您理解。真正的方向就像jzqa的回答,"environment variables"。
所以这里的问题是如何创建用户。我认为这至少回答了这一点,您可以在此处查看完整设置 https://github.com/Lus1t4nUm/mongo_docker_bootstrap
Mongo 图像提供 /docker-entrypoint-initdb.d/ 路径来部署自定义 .js 或 .sh 安装脚本。
检查此 post 以获取更多详细信息:
为了初始化mongo,使用初始用户-密码-数据库三元组和initdb脚本,只有一个docker-compose.yml,无需任何额外配置,您可以使用bitnami/mongo 图片。
就我而言,我没有 运行 我的脚本位于 /docker-入口点-initdb.d 设置环境变量后容器中的目录; MONGODB_USERNAME 和 MONGODB_PASSWORD(bitnami 图像的特定环境变量)因为 mongod 运行s 与 --auth 选项自动当你设置这些变量。因此,当容器正在执行脚本时,我遇到了身份验证错误。
因为,它正在连接到:mongodb://192.168.192.2:27017/compressors=disabled&gssapiServiceName=mongodb
TERMINAL LOG OF THE ERROR
第一个 DOCKER-撰写文件:
version: "3"
services:
mongodb:
container_name: mongodb
image: 'docker.io/bitnami/mongodb:4.2-debian-10'
ports:
- "27017:27017"
volumes:
- "mongodb_data:/bitnami/mongodb"
- "./mongodb/scripts:/docker-entrypoint-initdb.d"
environment:
- MONGODB_INITSCRIPTS_DIR=/docker-entrypoint-initdb.d
- MONGODB_USERNAME=some_username
- MONGODB_PASSWORD=some_password
- MONGODB_DATABASE=some_db_name
networks:
backend:
restart: unless-stopped
volumes:
mongodb_data:
networks:
backend:
driver: bridge
在 ./mongodb/scripts 路径下初始化 JS 文件:
let db = connect("localhost:27017/some_db_name");
db.auth("some_username", "some_password");
let collections = db.getCollectionNames();
let storeFound = false;
let index;
for(index=0; index<collections.length; index++){
if ("store" === collections[index]){
storeFound = true;
}
}
if(!storeFound ){
db.createCollection("store");
db.store.createIndex({"name": 1});
}
因此,我决定在检查 https://github.com/bitnami/bitnami-docker-mongodb/blob/master/4.2/debian-10/rootfs/opt/bitnami/scripts/libmongodb.sh 文件后向我的 docker-compose.yml 添加新的环境变量。
在这个sh文件中,有类似mongodb_custom_init_scripts()的函数来执行脚本。为了执行所有脚本文件,它 运行s mongodb_execute() 方法。在此方法中,在 mongod 实例启动且 运行 之后,mongo 客户端使用一些参数连接到 mongod 实例。
########################
# Execute an arbitrary query/queries against the running MongoDB service
# Stdin:
# Query/queries to execute
# Arguments:
# - User to run queries
# - Password
# - Database where to run the queries
# - Host (default to result of get_mongo_hostname function)
# - Port (default $MONGODB_PORT_NUMBER)
# - Extra arguments (default $MONGODB_CLIENT_EXTRA_FLAGS)
# Returns:
# None
########################
mongodb_execute() {
local -r user="${1:-}"
local -r password="${2:-}"
local -r database="${3:-}"
local -r host="${4:-$(get_mongo_hostname)}"
local -r port="${5:-$MONGODB_PORT_NUMBER}"
local -r extra_args="${6:-$MONGODB_CLIENT_EXTRA_FLAGS}"
local result
local final_user="$user"
# If password is empty it means no auth, do not specify user
[[ -z "$password" ]] && final_user=""
local -a args=("--host" "$host" "--port" "$port")
[[ -n "$final_user" ]] && args+=("-u" "$final_user")
[[ -n "$password" ]] && args+=("-p" "$password")
[[ -n "$extra_args" ]] && args+=($extra_args)
[[ -n "$database" ]] && args+=("$database")
"$MONGODB_BIN_DIR/mongo" "${args[@]}"
}
之后,我向 docker-compose 添加了新的环境变量,例如 MONGODB_ADVERTISED_HOSTNAME,MONGODB_PORT_NUMBER,并且,MONGODB_CLIENT_EXTRA_FLAGS
所以我的最终 docker-compose.yml 看起来像:
version: "3"
services:
mongodb:
container_name: mongodb
image: 'docker.io/bitnami/mongodb:4.2-debian-10'
ports:
- "27017:27017"
volumes:
- "mongodb_data:/bitnami/mongodb"
- "./mongodb/scripts:/docker-entrypoint-initdb.d"
environment:
- MONGODB_INITSCRIPTS_DIR=/docker-entrypoint-initdb.d
- MONGODB_USERNAME=some_username
- MONGODB_PASSWORD=some_password
- MONGODB_DATABASE=some_db_name
- MONGODB_ADVERTISED_HOSTNAME=localhost
- MONGODB_PORT_NUMBER=27017
- MONGODB_CLIENT_EXTRA_FLAGS=--authenticationDatabase=some_db_name
networks:
backend:
restart: unless-stopped
volumes:
mongodb_data:
networks:
backend:
driver: bridge
现在是通过这个连接的url:
mongodb://localhost:27017/?authSource=some_db_name&compressors=disabled &gssapiServiceName=mongodb
在你的项目目录中创建另一个目录docker-entrypoint-initdb.d
然后
文件树如下所示:
Project-directory
┣ docker-entrypoint-initdb.d
┃ ┗ mongo-init.js
┗ docker-compose.yaml
docker-compose.yml包含:
version: "3.7"
services:
mongo:
container_name: container-mongodb
image: mongo:latest
restart: always
ports:
- 27017:27017
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: password
MONGO_INITDB_DATABASE: root-db
volumes:
- ./docker-entrypoint-initdb.d/mongo-init.js:/docker-entrypoint-initdb.d/mongo-init.js:ro
mongo-init.js
包含 javascript 代码以创建具有不同角色的用户。
print("Started Adding the Users.");
db = db.getSiblingDB("admin");
db.createUser({
user: "userx",
pwd: "1234",
roles: [{ role: "readWrite", db: "admin" }],
});
print("End Adding the User Roles.");
您可以根据需要修改mongo-init.js
。
我正在尝试创建某种类型的脚本,该脚本将使用 mongodb 创建一个 docker 并自动创建一个用户。
我通常可以使用 docker-compose 管理我的 docker 图片,但这次,我不知道该怎么做。
基本上,这是我必须做的:
- clean/destroy 容器 (
docker-compose down
) - 使用 mongodb 创建一个 docker 容器并启动它(没有
--auth parameter
) - 执行包含
db.createUser()
的java脚本
- 停止容器
- 使用
--auth
参数重新启动同一个容器,以允许使用在 java 脚本 中创建的用户登录
我找不到如何使用 docker-compose 正确地做到这一点,因为当它启动时,我必须给它命令 --auth。如果这样做,我将无法执行我的 java 脚本来添加我的用户。 MongoDB 如果没有用户且未提供 --auth 参数,则允许在不登录的情况下创建用户。
我想自动执行,我不想手动执行某些命令。目标是拥有一个可以在每次集成测试之前执行的脚本,以从干净的数据库开始。
这是我的项目:
integration-test/src/test/resources/scripts/docker-compose.yml
mongodb:
container_name: mongo
image: mongo
ports:
- "27017:27017"
volumes:
- .:/setup
command: --auth
integration-test/src/test/resources/scripts/docker-init.sh
docker-compose down
docker-compose up -d
sleep 1
docker exec mongo bash -c "mongo myDatabase /setup/mongodb-setup.js"
integration-test/src/test/resources/scripts/mongodb-setup.js
db.createUser(
{
user: "myUser",
pwd: "myPassword",
roles: [
{ role: "readWrite", db: "myDatabase" }
]
})
找到一种使用新参数重新启动容器的方法(在本例中为 --auth
)会有所帮助,但我找不到该怎么做(docker 启动不带参数).
知道我应该怎么做吗?
如果没有,我仍然可以使用一些 Java 代码或其他东西从我的数据库中删除所有内容,但我想要一个完整的 mongodb docker 使用脚本创建的设置。
编辑: tutumcloud 存储库已弃用且不再维护,请参阅其他答案
我建议你使用环境变量来设置mongo用户、数据库和密码。 tutum
(拥有者Docker)发布了一张非常好的图片
https://github.com/tutumcloud/mongodb
docker run -d -p 27017:27017 -p 28017:28017 -e MONGODB_USER="user" -e MONGODB_DATABASE="mydatabase" -e MONGODB_PASS="mypass" tutum/mongodb
您可以将这些变量转换为 docker-compose 环境变量。您不必对其进行硬编码。
environment:
MONGODB_USER: "${db_user_env}"
MONGODB_DATABASE: "${dbname_env}"
MONGODB_PASS: "${db_pass}"
此配置将从您会话的环境变量中读取。
向 mongo 命令添加 --noauth 选项
从我的 docker-compose.yml 文件中提取
mongors:
image: mongo:latest
command: mongod --noprealloc --smallfiles --replSet mongors2 --dbpath /data/db --nojournal --oplogSize 16 --noauth
environment:
TERM: xterm
volumes:
- ./data/mongors:/data/db
阅读官方mongo docker page后,我发现即使使用了 auth 选项,您也可以一次性创建一个管理员用户。这没有很好的记录,但它确实有效(希望它不是一个功能)。 因此,您可以一直使用 auth 选项。
我创建了一个 github 存储库,其中包含包含要使用的命令的脚本。 运行 最重要的命令行是:
docker exec db_mongodb mongo admin /setup/create-admin.js
docker exec db_mongodb mongo admin /setup/create-user.js -u admin -p admin --authenticationDatabase admin
第一行将创建管理员用户(并且 mongo 即使使用 auth 选项也不会抱怨)。第二行将创建您的 "normal" 用户,使用第一行的管理员权限。
我就是这样做的,我的要求是与 mongodb 一起启动一些容器,其他容器希望用户在出现时在场,这对我有用。好的部分是,mongoClientTemp 在命令执行后退出,因此容器不会停留。
version: '2'
services:
mongo:
image: mongo:latest
container_name: mongo
ports:
- "27017:27017"
volumes:
- /app/hdp/mongo/data:/data/db
mongoClientTemp:
image: mongo:latest
container_name: mongoClientTemp
links:
- mongo:mongo
command: mongo --host mongo --eval "db.getSiblingDB('dashboard').createUser({user:'db', pwd:'dbpass', roles:[{role:'readWrite',db:'dashboard'}]});"
depends_on:
- mongo
another-container:
image: another-image:v01
container_name: another-container
ports:
- "8080:8080"
volumes:
- ./logs:/app/logs
environment:
- MONGODB_HOST=mongo
- MONGODB_PORT=27017
links:
- mongo:mongo
depends_on:
- mongoClientTemp
官方 mongo 镜像现在支持以下环境变量,可以在 docker-compose 中使用,如下所示:
environment:
- MONGO_INITDB_ROOT_USERNAME=user
- MONGO_INITDB_ROOT_PASSWORD=password
- MONGO_INITDB_DATABASE=test
更多解释请见:
文件:docker-compose.yaml
mongo:
image: mongo:latest
volumes_from:
- data
ports:
- "27017:27017"
command: --auth
container_name: "db_mongodb"
data:
image: mongo:latest
volumes:
- /var/lib/mongo
- ./setup:/setup
command: "true"
container_name: "db_mongodb_data"
文件:.buildMongo.sh
#!/bin/sh
docker-compose down
docker-compose up -d
sleep 1
docker exec db_mongodb mongo admin /setup/create-admin.js
docker exec db_mongodb mongo myDb /setup/create-user.js -u admin -p admin --authenticationDatabase admin
create-admin.js 和 create-user.js 文件是您使用 mongo shell 使用的命令。因此,它们必须易于您理解。真正的方向就像jzqa的回答,"environment variables"。 所以这里的问题是如何创建用户。我认为这至少回答了这一点,您可以在此处查看完整设置 https://github.com/Lus1t4nUm/mongo_docker_bootstrap
Mongo 图像提供 /docker-entrypoint-initdb.d/ 路径来部署自定义 .js 或 .sh 安装脚本。
检查此 post 以获取更多详细信息:
为了初始化mongo,使用初始用户-密码-数据库三元组和initdb脚本,只有一个docker-compose.yml,无需任何额外配置,您可以使用bitnami/mongo 图片。
就我而言,我没有 运行 我的脚本位于 /docker-入口点-initdb.d 设置环境变量后容器中的目录; MONGODB_USERNAME 和 MONGODB_PASSWORD(bitnami 图像的特定环境变量)因为 mongod 运行s 与 --auth 选项自动当你设置这些变量。因此,当容器正在执行脚本时,我遇到了身份验证错误。
因为,它正在连接到:mongodb://192.168.192.2:27017/compressors=disabled&gssapiServiceName=mongodb
TERMINAL LOG OF THE ERROR
第一个 DOCKER-撰写文件:
version: "3"
services:
mongodb:
container_name: mongodb
image: 'docker.io/bitnami/mongodb:4.2-debian-10'
ports:
- "27017:27017"
volumes:
- "mongodb_data:/bitnami/mongodb"
- "./mongodb/scripts:/docker-entrypoint-initdb.d"
environment:
- MONGODB_INITSCRIPTS_DIR=/docker-entrypoint-initdb.d
- MONGODB_USERNAME=some_username
- MONGODB_PASSWORD=some_password
- MONGODB_DATABASE=some_db_name
networks:
backend:
restart: unless-stopped
volumes:
mongodb_data:
networks:
backend:
driver: bridge
在 ./mongodb/scripts 路径下初始化 JS 文件:
let db = connect("localhost:27017/some_db_name");
db.auth("some_username", "some_password");
let collections = db.getCollectionNames();
let storeFound = false;
let index;
for(index=0; index<collections.length; index++){
if ("store" === collections[index]){
storeFound = true;
}
}
if(!storeFound ){
db.createCollection("store");
db.store.createIndex({"name": 1});
}
因此,我决定在检查 https://github.com/bitnami/bitnami-docker-mongodb/blob/master/4.2/debian-10/rootfs/opt/bitnami/scripts/libmongodb.sh 文件后向我的 docker-compose.yml 添加新的环境变量。
在这个sh文件中,有类似mongodb_custom_init_scripts()的函数来执行脚本。为了执行所有脚本文件,它 运行s mongodb_execute() 方法。在此方法中,在 mongod 实例启动且 运行 之后,mongo 客户端使用一些参数连接到 mongod 实例。
########################
# Execute an arbitrary query/queries against the running MongoDB service
# Stdin:
# Query/queries to execute
# Arguments:
# - User to run queries
# - Password
# - Database where to run the queries
# - Host (default to result of get_mongo_hostname function)
# - Port (default $MONGODB_PORT_NUMBER)
# - Extra arguments (default $MONGODB_CLIENT_EXTRA_FLAGS)
# Returns:
# None
########################
mongodb_execute() {
local -r user="${1:-}"
local -r password="${2:-}"
local -r database="${3:-}"
local -r host="${4:-$(get_mongo_hostname)}"
local -r port="${5:-$MONGODB_PORT_NUMBER}"
local -r extra_args="${6:-$MONGODB_CLIENT_EXTRA_FLAGS}"
local result
local final_user="$user"
# If password is empty it means no auth, do not specify user
[[ -z "$password" ]] && final_user=""
local -a args=("--host" "$host" "--port" "$port")
[[ -n "$final_user" ]] && args+=("-u" "$final_user")
[[ -n "$password" ]] && args+=("-p" "$password")
[[ -n "$extra_args" ]] && args+=($extra_args)
[[ -n "$database" ]] && args+=("$database")
"$MONGODB_BIN_DIR/mongo" "${args[@]}"
}
之后,我向 docker-compose 添加了新的环境变量,例如 MONGODB_ADVERTISED_HOSTNAME,MONGODB_PORT_NUMBER,并且,MONGODB_CLIENT_EXTRA_FLAGS
所以我的最终 docker-compose.yml 看起来像:
version: "3"
services:
mongodb:
container_name: mongodb
image: 'docker.io/bitnami/mongodb:4.2-debian-10'
ports:
- "27017:27017"
volumes:
- "mongodb_data:/bitnami/mongodb"
- "./mongodb/scripts:/docker-entrypoint-initdb.d"
environment:
- MONGODB_INITSCRIPTS_DIR=/docker-entrypoint-initdb.d
- MONGODB_USERNAME=some_username
- MONGODB_PASSWORD=some_password
- MONGODB_DATABASE=some_db_name
- MONGODB_ADVERTISED_HOSTNAME=localhost
- MONGODB_PORT_NUMBER=27017
- MONGODB_CLIENT_EXTRA_FLAGS=--authenticationDatabase=some_db_name
networks:
backend:
restart: unless-stopped
volumes:
mongodb_data:
networks:
backend:
driver: bridge
现在是通过这个连接的url:
mongodb://localhost:27017/?authSource=some_db_name&compressors=disabled &gssapiServiceName=mongodb
在你的项目目录中创建另一个目录docker-entrypoint-initdb.d
然后
文件树如下所示:
Project-directory
┣ docker-entrypoint-initdb.d
┃ ┗ mongo-init.js
┗ docker-compose.yaml
docker-compose.yml包含:
version: "3.7"
services:
mongo:
container_name: container-mongodb
image: mongo:latest
restart: always
ports:
- 27017:27017
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: password
MONGO_INITDB_DATABASE: root-db
volumes:
- ./docker-entrypoint-initdb.d/mongo-init.js:/docker-entrypoint-initdb.d/mongo-init.js:ro
mongo-init.js
包含 javascript 代码以创建具有不同角色的用户。
print("Started Adding the Users.");
db = db.getSiblingDB("admin");
db.createUser({
user: "userx",
pwd: "1234",
roles: [{ role: "readWrite", db: "admin" }],
});
print("End Adding the User Roles.");
您可以根据需要修改mongo-init.js
。