【MongoDB】在启动MongoDB的Docker容器时,创建用于认证的用户。(在启动MongoDB的Docker容器时,需要创建一个用于认证的用户。)
使用MongoDB的Docker容器进行开发时,考虑到在生产环境中也要使用,因此已经进行了设置,以便在应用程序和终端从中连接时进行身份验证。
在启动容器后,自己进行命令设置或编写Shell脚本并不明智,所以我在调查时发现官方镜像已经被设计成可以插入初始数据。我调查了这种方法和背后的实际操作,所以写下来作为备忘录。
环境
Docker Desktop for Mac ver 2.0.0.3
Docker Engine ver 18.09.2
MongoDB Docker Image tag 4.1-bionic
创建认证用户的方法。
使用JavaScript创建用户
const user = {
user: 'staff',
pwd: 'staff_password',
roles: [{
role: 'readWrite',
db: 'test'
}]
};
db.createUser(user);
通过这个脚本,将创建一个名为staff、密码为staff_password、具有对testDB读写权限的用户。值得一提的是,可以将多个角色授予用户。
要连接到MongoDB,您需要执行mongo test -u staff -p staff_password命令。
啟用驗證
MongoDB是一种开源的文档数据库管理系统。
MongoDB默认情况下不启用访问控制。您可以使用–auth或security.authorization设置来启用授权。
正如所述,默认情况下,认证和授权是禁用的。创建身份验证用户是没有意义的,除非启用认证和授权。
要启用它,有两种方法,如引文所述,一种是使用–auth命令选项,另一种是将配置文件中的security.authorization设置为enabled。
Dockerfile的翻译是:Docker文件
为了在启动时创建认证用户,需要将createUser.js放置在/docker-entrypoint-initdb.d目录下。然后,启用认证和授权的Dockerfile如下所示。
FROM mongo:4.1-bionic
COPY createUser.js /docker-entrypoint-initdb.d/
EXPOSE 27017
CMD ["mongod", "--auth"]
docker-entrypoint.sh的秘密
在MongoDB的Docker镜像中,当容器启动时会执行docker-entrypoint.sh脚本并插入初始数据。我打算解释一下这个Shell脚本在做什么。
创建root用户。
如果环境变量中设置了MONGO_INITDB_ROOT_USERNAME和MONGO_INITDB_ROOT_PASSWORD,将会创建root用户。该root用户的角色为root,可以访问所有资源。因此,如果不需要root用户,最好不要创建。
以下的部分是创建root用户的相关代码。
mongo=( mongo --host 127.0.0.1 --port 27017 --quiet )
if [ "$MONGO_INITDB_ROOT_USERNAME" ] && [ "$MONGO_INITDB_ROOT_PASSWORD" ]; then
rootAuthDatabase='admin'
"${mongo[@]}" "$rootAuthDatabase" <<-EOJS
db.createUser({
user: $(_js_escape "$MONGO_INITDB_ROOT_USERNAME"),
pwd: $(_js_escape "$MONGO_INITDB_ROOT_PASSWORD"),
roles: [ { role: 'root', db: $(_js_escape "$rootAuthDatabase") } ]
})
EOJS
fi
在脚本中,我们创建了一个用户名为MONGO_INITDB_ROOT_USERNAME,密码为MONGO_INITDB_ROOT_PASSWORD,角色为root的用户,并将其添加到admin数据库中。
插入初始数据
为了插入初始数据,您需要编写专门的Shell脚本或JavaScript。其他类型的脚本将被忽略。
如果插入脚本存放在/docker-entrypoint-initdb.d目录下,脚本将被执行。当然,如果将脚本放在其他目录下,则不会被执行。-当然这是理所当然的哈哈
不需要看这前面的内容了,我们来看看docker-entrypoint.sh文件的具体内容。
注意:行号只是为了说明而从1开始连续编号,并不与真实的源代码行号相同。
1 export MONGO_INITDB_DATABASE="${MONGO_INITDB_DATABASE:-test}"
2
3 for f in /docker-entrypoint-initdb.d/*; do
4 case "$f" in
5 *.sh) echo "$0: running $f"; . "$f" ;;
6 *.js) echo "$0: running $f"; "${mongo[@]}" "$MONGO_INITDB_DATABASE" "$f"; echo ;;
8 *) echo "$0: ignoring $f" ;;
9 esac
10 echo
11 done
① 第一行
② 首句
③ 开头
④ 首行
⑤ 首句话
将要操作的数据库存储在环境变量MONGO_INITDB_DATABASE中,并进行导出。默认情况下,目标数据库为test。
第三行
为了能够执行docker-entrypoint-initdb.d目录下的所有脚本,我使用for循环进行遍历。因此,您可以将多个脚本分开并放置在/docker-entrypoint-initdb.d目录下,以便按照执行内容进行分组。这样一来,您就可以避免在一个脚本中混杂写入各种内容。
第五行
正在执行Shell脚本,”.”表示读取并执行脚本的意思,起到类似于source命令的作用。
第六行
执行JavaScript代码。mongo命令有
您可以在mongo shell中指定一个.js文件,mongo将直接执行该JavaScript文件。
有一种功能可以直接执行JavaScript,不需要用node命令来执行。
`${mongo[@]}`在创建root用户的部分也有出现,但是指的是`mongo –host 127.0.0.1 –port 27017 –quiet`。
最后
這樣一來,我想你現在應該已經了解到了插入初始數據的方法和技巧了。
在開發中,創建連接用戶和插入測試數據時都會派上用場。不僅MongoDB,還有MySQL、PostgreSQL等數據庫也可以實現插入初始數據。
藉助這些方便的功能,我們可以快速輕鬆地搭建環境,並專注於主要的開發工作!
那麼,讓我們開始進入主題吧!
请查阅参考资料。
-
- mongo – Docker Hub
-
- Built-In Roles — MongoDB Manual
-
- Write Scripts for the mongo Shell — MongoDB Manual
-
- mongod — MongoDB Manual
-
- mongo/docker-entrypoint.sh
- mongo/Dockerfile