如何在启动时为MongoDB容器创建DB?
我和Docker一起工作,我有一个PHP、MySQL、Apache和Redis的堆栈。我现在需要添加MongoDB,因此我正在检查最新版本以及来自的文件,但我无法找到从如何在启动时为MongoDB容器创建DB?,mongodb,docker,docker-compose,Mongodb,Docker,Docker Compose,我和Docker一起工作,我有一个PHP、MySQL、Apache和Redis的堆栈。我现在需要添加MongoDB,因此我正在检查最新版本以及来自的文件,但我无法找到从docker compose.yml文件为容器设置默认DB、管理员用户/密码以及可能的身份验证方法的方法 在MySQL中,您可以设置一些环境变量,例如: db: image: mysql:5.7 env_file: .env environment: MYSQL_ROOT_PASSWORD: $
docker compose.yml
文件为容器设置默认DB、管理员用户/密码以及可能的身份验证方法的方法
在MySQL中,您可以设置一些环境变量,例如:
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有什么方法可以达到同样的效果吗?任何人都有一定的经验或解决方法吗?在启动时必须与数据库和管理员用户联系
当/data/db
目录中没有填充任何内容时,数据库初始化将在/docker entrypoint initdb.d/
中运行脚本
数据库初始化
mongo
容器映像提供了/docker entrypoint initdb.d/
路径来部署自定义.js
或.sh
安装脚本,这些脚本将在数据库初始化时运行一次<默认情况下,test
或MONGO\u INITDB\u数据库(如果在环境中定义)将运行code>.js
脚本
COPY mysetup.sh /docker-entrypoint-initdb.d/
或
一个简单的初始化文件,演示如何使用数据设置容器
集合、日志记录以及如何在出现错误时退出(用于结果检查)
管理员用户设置
控制“root”用户设置的环境变量包括
MONGO\u INITDB\u ROOT\u用户名
MONGO\u INITDB\u ROOT\u密码
docker run -d \
-e MONGO_INITDB_ROOT_USERNAME=admin \
-e MONGO_INITDB_ROOT_PASSWORD=password \
mongod
或Dockerfile
FROM docker.io/mongo
ENV MONGO_INITDB_ROOT_USERNAME admin
ENV MONGO_INITDB_ROOT_PASSWORD password
您不需要在命令行上使用
--auth
作为docker入口点。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"
版本:“3.3”
服务:
db:
图片:mongo
环境:
-MONGO_INITDB_ROOT_USERNAME=admin
-MONGO_INITDB_ROOT_密码=
端口:
- "27017:27017"
运行
docker compose up
时,您的mongo实例将自动运行并启用auth。您将拥有一个具有给定密码的管理员数据库。如果您希望从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
我已经为我的秘密使用了文件:选项,但是,您也可以使用外部:并在群中使用秘密
机密可用于容器中位于/var/run/secrets的任何脚本
Docker文档中有关于存储敏感数据的说明
您可以使用机密管理容器在运行时需要但不希望存储在映像或源代码管理中的任何敏感数据,例如:
用户名和密码
TLS证书和密钥
SSH密钥
其他重要数据,如数据库或内部服务器的名称
通用字符串或二进制内容(大小不超过500 kb)这里有一个工作解决方案,它可以创建具有密码的
管理员用户
用户、附加数据库(测试数据库
)以及该数据库中的测试用户
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: 'test-database',
},
],
});
棘手的是要理解*.js文件是未经身份验证运行的。
解决方案在
admin
数据库中将脚本验证为admin用户MONGO\u INITDB\u数据库管理是必需的,否则脚本将针对test
db执行。查看.UPD的源代码。UPD今天,我要查看Docker Swarm、secrets和configs。我将使用docker compose
和.env
文件运行它。只要我不需要自动缩放。如果我这样做,我可能会选择k8s。和数据库密码,根帐户或不。。。当您在未连接到外部世界的容器中运行单个数据库时,它们真的很重要吗?。。我想知道您对此有何看法,但堆栈溢出可能不太适合这种通信
Mongo映像可能会受到Mongo_INITDB_数据库的影响,但它不会创建数据库。此变量确定运行/docker entrypoint initdb.d/*
时的当前数据库。由于您在Mongo执行的脚本中使用了环境变量,因此我使用了一个shell脚本:
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 = '$MONGO_INITDB_ROOT_PASSWORD';
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
秘密不能存储在文件中
这是另一个更干净的解决方案,使用docker compose
和js
脚本
本例假设两个文件(docker-compose.yml和mongo init.js)位于同一文件夹中
docker-compose.yml
注意:docker entrypoint init.d文件夹中的代码仅在数据库以前从未初始化过的情况下执行。鉴于此.env
文件:
DB_NAME=foo
DB_USER=bar
DB_PASSWORD=baz
这个mongo init.sh
文件:
DB_NAME=foo
DB_USER=bar
DB_PASSWORD=baz
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
将创建管理员数据库和管理员用户,验证为管理员用户,然后创建真实数据库并添加真实用户:
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:
我的答案基于@x-yuri提供的答案;但我的情况有点不同。我想要一个包含脚本的图像,而不是不需要绑定就绑定并装载它
mongo init.sh
——不知道是否需要,但我运行了chmod+x mongo init.sh
:
#/B
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 up --build -d mongodb
DB_NAME=foo
DB_USER=bar
DB_PASSWORD=baz
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:
FROM mongo:3.6
COPY mongo-init.sh /docker-entrypoint-initdb.d/mongo-init.sh
CMD [ "/docker-entrypoint-initdb.d/mongo-init.sh" ]
docker volume rm db_volume
docker-compose down
docker volume rm <projectfolder>_mongodb--vol
mongodb://db_1_service_user:<password>@mongodb:27017/db_1
mongodb://db_2_service_user:<password>@mongodb:27017/db_2