最近在被割韭菜,遇到了一个问题,那就是如何在初始化mongodb容器的时候就把一些数据导入进去,并且是从一个json后缀的文件中导入。我翻遍国内平台,啥都解决不了,看了dockerhub中的mongo官方的用法也是含糊其辞。于是,我跑去stackoverflow和google搜了一下,然后又折腾了一会总算出来了。下面是两个相关的链接:
参考上面两个链接基本就可以解决,不过我遇到了几个坑,所以记录一下
dockerhub mongo
三个环境变量:
MONGO_INITDB_ROOT_USERNAME
MONGO_INITDB_ROOT_PASSWORD
MONGO_INITDB_DATABASE
前两个很好理解,而第三个来看官网的狡辩:
This variable allows you to specify the name of a database to be used for creation scripts in /docker-entrypoint-initdb.d/*.js (see Initializing a fresh instance below). MongoDB is fundamentally designed for “create on first use”, so if you do not insert data with your JavaScript files, then no database is created.
也就是只有在/docker-entrypoint-initdb.d/*.js文件中做插入操作才会生成这个数据库。(mongodb可以执行/docker-entrypoint-initdb.d文件夹下.js文件和.sh文件)
然后官网关于如何初始化数据库实例:
Initializing a fresh instance
When a container is started for the first time it will execute files with extensions .sh and .js that are found in /docker-entrypoint-initdb.d. Files will be executed in alphabetical order. .js files will be executed by mongo using the database specified by the MONGO_INITDB_DATABASE variable, if it is present, or test otherwise. You may also switch databases within the .js script.
ok,看完两个链接和官网文档,我做了如下配置:
首先看看目录结构
这里注意当有多个sh和js文件在/docker-entrypoint-initdb.d文件夹下时,是按照字母顺序执行的,所以,这里js要先于sh执行,先创建数据库和collection,在导入json数据。
docker-compose.yml
如下(这里没用MONGO_INITDB_DATABASE
,是因为加进来sh文件里引用$MONGO_INITDB_DATABASE
也会报错,暂时还没解决,可以自己试试,可以看看这儿:How can I pass environment variables to mongo docker-entrypoint-initdb.d?):
...
jiefang-mongo:
container_name: jiefang-mongo
image: mongo
build:
context: ./mongo
dockerfile: dockerfile
ports:
- "27017:27017"
volumes:
- ./mongo/conf/mongod.conf:/etc/mongod.conf
- ./mongo/data:/data/db
- ./mongo/init:/docker-entrypoint-initdb.d
...
mongo的dockerfile
如下(没什么作用,主要缓存原始镜像,如果在compose里直接做镜像,每次改动还要重新拉取原始镜像):
FROM mongo
MAINTAINER bty
01-init.js
文件如下:
// Create user
dbAdmin = db.getSiblingDB("admin");
dbAdmin.createUser({
user: "mongo",
// 希望有机会值10个btc
pwd: "10btc",
roles: [{ role: "userAdminAnyDatabase", db: "admin" }],
mechanisms: ["SCRAM-SHA-1"],
});
// Authenticate user
dbAdmin.auth({
user: "mongo",
pwd: "10btc",
mechanisms: ["SCRAM-SHA-1"],
digestPassword: true,
});
// Create DB and collection
db = new Mongo().getDB("jiefangProj");
db.createCollection("t_xcp", { capped: false });
02-init.sh
如下:
echo "########### Loading data to Mongo DB ###########"
mongoimport --jsonArray --db jiefangProj --file /docker-entrypoint-initdb.d/data.json --collection t_xcp
echo "########### Mongo DB data Loaded ###########"
这个02-init.sh
可把我坑惨了,最开始是:
echo "########### Loading data to Mongo DB ###########"
mongoimport --jsonArray --db jiefangProj --collection t_xcp --file /docker-entrypoint-initdb.d/data.json
echo "########### Mongo DB data Loaded ###########"
然后报错,说\n
不是命令,就是什么空格、换行导致的,然后我把sh文件变紧凑了
echo "########### Loading data to Mongo DB ###########"
mongoimport --jsonArray --db jiefangProj --collection t_xcp --file /docker-entrypoint-initdb.d/data.json
echo "########### Mongo DB data Loaded ###########"
然后一直报错:找不到这个文件或文件夹,搞了一下午。
我又把参数换了个位置:
echo "########### Loading data to Mongo DB ###########"
mongoimport --db jiefangProj --collection t_xcp --file /docker-entrypoint-initdb.d/data.json --jsonArray
echo "########### Mongo DB data Loaded ###########"
然后也报错,不过错误不同,说jsonArray不识别,我就用我聪明的大脑想到了,这个sh文件格式是不是有问题,但是搞了半天还是没找到原因。
最后吃完晚饭,又随便换了个参数位置:
echo "########### Loading data to Mongo DB ###########"
mongoimport --jsonArray --db jiefangProj --file /docker-entrypoint-initdb.d/data.json --collection t_xcp
echo "########### Mongo DB data Loaded ###########"
后记,其实还是不行,最后不得以把两个echo指令删除,只保留哪个mongoimport,这真的没问题了。