这些天一直在研究如何用docker-compose
对mongodb@7
进行部署,但网上的文章良莠不齐,而且基本上都已经过时。所以为了方便大家进行部署也方便自己进行记录,特意写了下面的文章。。
以下经验均来自于dockerhub
上的mongo 库的官方解释以及对github
原码的Dockerfile文件进行的分析,如有纰漏请指出。
配置
默认你的机器上已经安装好了docker
,如果你安装了docker
,那么docker-compose
会被一起安装到你的系统中。 我们在home
目录中创建一个docker-compose.yml
文件,并写入如下代码
yml
version: '3'
services: # 集合
...
docker_mongo:
image: mongo:latest
restart: always
container_name: mongodb
ports:
- 27017:27017
environment:
MONGO_INITDB_ROOT_USERNAME: ${MONGO_INITDB_ROOT_USERNAME}
MONGO_INITDB_ROOT_PASSWORD: ${MONGO_INITDB_ROOT_PASSWORD}
volumes:
- /home/ubuntu/mongodb/data/db:/data/db
- /home/ubuntu/mongodb/data/config:/etc/mongo
command:
- --wiredTigerCacheSizeGB
- '1.5'
其实到这步我们就已经配置好了一个mongodb@7
的docker
,但还有很多的细节需要说明
我们还可以同时安装一个用Node.js
和express
实现的数据库管理工具(docker
官方推荐)
yml
version: '3'
services: # 集合
...
docker_mongo:
...
docker_mongo-express:
image: mongo-express
restart: always
ports:
- 8081:8081
environment:
ME_CONFIG_MONGODB_ADMINUSERNAME: ${MONGO_INITDB_ROOT_USERNAME}
ME_CONFIG_MONGODB_ADMINPASSWORD: ${MONGO_INITDB_ROOT_PASSWORD}
ME_CONFIG_MONGODB_URL: mongodb://${MONGO_INITDB_ROOT_USERNAME}:${MONGO_INITDB_ROOT_PASSWORD}@docker_mongo:27017/
实际上我觉得不怎么好用,推荐官方的mongo-compass
字段解析
docker_mongo
:默认会被用做该docker的主机名,其实可以随便取,但要注意,在某些情况如上面进行mongo-express
:配置的时候,我们ME_CONFIG_MONGODB_URL
环境变量使用的主机地址要与该值保持一致。image
:表示我们要使用的镜像版本,我们这里默认是最新版,也就是7.0的版本。restart
:使用always
表示只要该容器挂掉了,无论什么原因都重新启动。container_name
:是用来设置启动后容器的名称的,该项不是必需的,但可以增强语义化,如图所示
-
ports
: 用来配置对外暴露的接口,格式为外部:内部
我们这里是把容器内部的27107映射到宿主机的27107端口,以便外部直接访问。 -
environment
: 该字段是容器的环境变量- 根据
mongo
的Dockerfile
以及dockerhub
中的文档可知,如果我们提供MONGO_INITDB_ROOT_USERNAME
和MONGO_INITDB_ROOT_PASSWORD
这两个变量的值,容器就会创建一个root权限的用户,并且以--auth
模式运行;如果不提供,则是无密码模式
官方表述
sqlBoth variables are required for a user to be created. If both are present then MongoDB will start with authentication enabled (`mongod --auth`)
docker-entrypoint.sh 内配置
sh// 使用--auth模式 if [ "$MONGO_INITDB_ROOT_USERNAME" ] && [ "$MONGO_INITDB_ROOT_PASSWORD" ]; then # if we have a username/password, let's set "--auth" _mongod_hack_ensure_arg '--auth' "$@" set -- "${mongodHackedArgs[@]}" shouldPerformInitdb='true' ... // 创建root权限账户 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
- 这两个环境变量的值我没有硬编码在
docker-compose
的配置文件中,而是写在了与docker-compose.yml
同级的.env
文件中,docker-compose
在执行的时候会自动从.env
文件中读取环境变量的值。
sh# .env # docker-compose variable # mongodb数据库环境变量只在db数据本地不存在时才会生效 MONGO_INITDB_ROOT_USERNAME=*** MONGO_INITDB_ROOT_PASSWORD=***
- 根据
-
volumes
: 这是容器的持久化设置,使得当容器被销毁重新生成时,容器存储的数据还在。- 这里有一个细节需要注意,我们使用环境变量启动了容器以后,该自动生成的
root
用户就被固定下来,不会因重新生成容器而改变;如果需要完全重置一个容器,需要先手动删除挂载到/home/ubuntu/mongodb/data/db
上的数据,再进行生成容器。 /home/ubuntu/mongodb/data/config:/etc/mongo
挂载这个路径可以在启动容器的时候使用自定义的mongodb
配置文件。你可以在/home/ubuntu/mongodb/data/config
增加mongod.conf
配置文件(参考官方配置)然后在启动容器的时候追加--config /etc/mongo/mongod.conf
命令,例:
bashdocker run --name some-mongo -v /my/custom:/etc/mongo -d mongo --config /etc/mongo/mongod.conf
- 如果是
docker-compose
则可以追加到command
字段后面,例如:
bashdocker_mongo: ... command: - --wiredTigerCacheSizeGB - '1.5' - --config - /etc/mongo/mongod.conf
- 这里有一个细节需要注意,我们使用环境变量启动了容器以后,该自动生成的
-
command
: 该命令是用来替换Dockerfile
里的默认命令CMD
的,根据Dockerfile
中的配置css... COPY docker-entrypoint.sh /usr/local/bin/ ENTRYPOINT ["docker-entrypoint.sh"] EXPOSE 27017 CMD ["mongod"]
执行时默认行为如:
docker-entrypoint.sh mongod
写了
command
后相当于替换了mongod:arduinodocker-entrypoint.sh --config /etc/mongo/mongod.conf # docker-entrypoint里有逻辑自动添加mongo命令
--wiredTigerCacheSizeGB
用来设置该容器的缓存大小
启动docker
bash
# 在docker-compose.yml 目录下执行
docker-compose up -d
总结
好了,我们已经完成的docker
版mongodb
的配置。你可以尝试使用exec
命令进入容器,看看是否创建成功root
用户。
bash
docker exec -it mongodb bash
mongosh
perl
use admin
db.auth('root', '***')
# {ok: 1}
db.getUsers()