docker-compose mongo 启动mongo容器后如何执行脚本创建用户数据库问题

系统版本:

Docker version 20.10.7, build f0df350

docker-compose version 1.29.2, build 5becea4c

1.docker-compose文件和start.sh

环境变量:Linux下必须export声明两个环境变量,注意这个账户同时也是创建的数据库的连接用户密码

export MONGO_INITDB_ROOT_USERNAME=<用户名>
export MONGO_INITDB_ROOT_PASSWORD=<密码>

目录:/home/user/docker-compose.yml

镜像:mongo:6.0.10

容器名:mongobss

挂载卷:data/db数据目录  start.sh后创建用户和库的脚本

环境变量:定义初始的mongo root角色用户

privileged:给予容器高权限

version: '3'
services:
  mongodb:
    image: mongo:6.0.10
    container_name: mongobss
    ports:
        - 27017:27017
    privileged: true
    volumes:
        - "./data/db:data/db"
        - "./start.sh:/docker-entrypoint-initdb.d/start.sh"  #这里是关键点涉及到mongo官方打包镜像时定义的sh启动文件在3中讲解
    environment:
      - MONGO_INITDB_ROOT_USERNAME=${MONGO_INITDB_ROOT_USERNAME}
      - MONGO_INITDB_ROOT_PASSWORD=${MONGO_INITDB_ROOT_PASSWORD}
    tty: true

 

目录:/home/user/start.sh

set -e:遇到错误shell不退出

mongosh:mongo高版本的命令行工具替代了原有的mongo,该脚本使用mongosh创建了初始的用户和库

#!/bin/bash
set -e
echo "Creating database: <库名>"
mongosh --username ${MONGO_INITDB_ROOT_USERNAME} --password ${MONGO_INITDB_ROOT_PASSWORD}  <<EOF
use admin
use <库名>
db.createUser({
  user:  "${MONGO_INITDB_ROOT_USERNAME}",
  pwd: "${MONGO_INITDB_ROOT_PASSWORD}",
  roles: [{ role: "readWrite", db: "<库名>" }]
})
EOF

2.启动容器:

目录:/home/user

命令:

cd /home/user
export 用户变量
export 密码变量
//能联网
docker pull mongo:6.0.10
//内网环境
//需要mongo 6.0.10的镜像tar, 一半网上找不到,可以在vmware中pull一个下来执行 docker save -o mongo.tar <镜像ID> 可以保存为tar包再上传到内网服务器
docker load -i mongo.tar
docker-compose up -d 
//查看容器运行状态,测试中初始化的时长大概在40秒左右完成脚本执行,其他服务才能连上mongo,如果有其他服务连接mongo建议发起一个sleep等待这个时间
docker ps
dcoker logs -f monogobss
//成功的日志输出

{"t":{"$date":"2023-12-16T04:42:41.548+00:00"},"s":"I", "c":"STORAGE", "id":22262, "ctx":"initandlisten","msg":"Timestamp monitor starting"}
{"t":{"$date":"2023-12-16T04:42:41.550+00:00"},"s":"I", "c":"NETWORK", "id":23015, "ctx":"listener","msg":"Listening on","attr":{"address":"/tmp/mongodb-27017.sock"} }
{"t":{"$date":"2023-12-16T04:42:41.550+00:00"},"s":"I", "c":"NETWORK", "id":23015, "ctx":"listener","msg":"Listening on","attr":{"address":"0.0.0.0"}}
{"t":{"$date":"2023-12-16T04:42:41.550+00:00"},"s":"I", "c":"NETWORK", "id":23016, "ctx":"listener","msg":"Waiting for connections","attr":{"port":27017,"ssl":"off"}}
{"t":{"$date":"2023-12-16T04:42:44.816+00:00"},"s":"I", "c":"NETWORK", "id":22943, "ctx":"listener","msg":"Connection accepted","attr":{"remote":"192.168.208.3:51104","uuid":"66225b3a-525e-450c-9d2b-a97d3bf173c9","connectionId":1,"connectionCount":1}}

3.docker-entrypoint-initdb.d作用:

mongo官方ENTRYPOINT容器入口文件:

https://github.com/docker-library/mongo/blob/master/docker-entrypoint.sh

这是在mongo官方文档查到的他们在构建镜像时 ENTRYPOINT 指定的容器启动端口文件docker-entrypoint.sh,当docker启动mongo容器时mongo首先会执行该这个脚本。

b70ce161a9f4   mongo:6.0.10   "docker-entrypoint.s…"   2 hours ago   Up 2 hours   0.0.0.0:27017->27017/tcp, :::27017->27017/tcp   mongobss

该脚本一共420行大多部分都是启动mongo进程的准备,主要关注的是最后几行,for循环读取/docker-entrypoint-initdb.d/ 该文件下的.sh .js格式脚本去执行,如果按照常规方法使用docker-compose的command字段会替换掉ENTRYPOINT 指定的启动文件也就无法启动mongo进程,但是采用 1 中volume挂载方式将脚本放入for指定的目录下,就会自动执行。

                export MONGO_INITDB_DATABASE="${MONGO_INITDB_DATABASE:-test}"
                echo
                for f in /docker-entrypoint-initdb.d/*; do
                        case "$f" in
                                *.sh) echo "$0: running $f"; . "$f" ;;
                                *.js) echo "$0: running $f"; "${mongo[@]}" "$MONGO_INITDB_DATABASE" "$f"; echo ;;
                                *)    echo "$0: ignoring $f" ;;
                        esac
                        echo
                done

4.外部程序使用mongo:

java -jar启动jar包为例:

假设你的配置文件引用的是环境变量,要注意因为mongo容器启动时间较长我们主程序要等待mongo容器初始化完成在发起链接请求mongo,可以在服务的启动文件sleep 45秒左右

[root@ config]# vi application.properties 
spring.data.mongodb.uri=${SPRING_DATA_MONGODB_URI}

 

这是docker-compose启动服务容器时环境变量的写法:要注意这个compose文件有两个容器 1 mongo的container_name=mongodb 2 jar包的应用程序,根据docker网络的特性可以直接使用hostname引用mongo 
environment:
      - SPRING_DATA_MONGODB_URI=mongodb://${MONGO_INITDB_ROOT_USERNAME}:${MONGO_INITDB_ROOT_PASSWORD}@mongodb:27017/BSStructure

 

 

 

 

 

 

 

热门相关:写给鼹鼠先生的情书   我有一张均富卡   无上崛起   陆鸣至尊神殿   魔葫