如何使用 docker-compose 为 mongo 数据库播种?

我正在尝试分发一组连接的应用程序,这些应用程序运行在几个链接的容器中,其中包括一个 mongo 数据库,该数据库需要:

  • 包含一些种子数据的分布;
  • 允许用户添加其他数据。

理想情况下,数据还将保存在链接的数据卷容器中。

我可以使用一个不挂载任何卷的 mongo基本实例(dockerhub image: psychemedia/mongo_nomount-这实际上是没有 VOLUME /data/db语句的基本 mongo Dockerfile)和一个 Dockerfile配置将数据放到 mongo容器中,如下所示:

ADD . /files
WORKDIR /files
RUN mkdir -p /data/db && mongod --fork --logpath=/tmp/mongodb.log && sleep 20 && \
mongoimport  --db testdb --collection testcoll  --type csv --headerline --file ./testdata.csv  #&& mongod --shutdown

其中 ./testdata.csv与 Dockerfile 位于同一目录(./mongo-with-data)中。

我的 docker-compose 配置文件包括以下内容:

mongo:
#image: mongo
build: ./mongo-with-data
ports:
- "27017:27017"
#Ideally we should be able to mount this against a host directory
#volumes:
#  - ./db/mongo/:/data/db
#volumes_from:
#  - devmongodata


#devmongodata:
#    command: echo created
#    image: busybox
#    volumes:
#       - /data/db

每当我尝试挂载一个卷时,似乎原始的种子数据(存储在 /data/db中)被删除了。我猜想,当一个卷安装到 /data/db时,它将替换当前存在的任何内容。

也就是说,Docker 用户指南表明: 在创建容器时初始化卷。如果容器的基本映像包含指定挂载点的数据,则在卷初始化时将现有数据复制到新卷中?因此,如果我在播种 RUN命令之后放置 VOLUME 命令,那么我希望数据保持不变?

那我做错了什么?

从长远来看,我想自动构建几个链接容器,然后分发一个 Vagrantfile/docker 组合 YAML 文件,它将启动一组链接应用程序,其中包括一个预先种子的 mongo数据库和一个(部分预先填充的)持久数据容器。

78585 次浏览

To answer my own question:

  • simple YAML file to create simple mongo container linked to a data volume container, fired up by Vagrant docker compose.
  • in the Vagrantfile, code along the lines of:

config.vm.provision :shell, :inline => <<-SH docker exec -it -d vagrant_mongo_1 mongoimport --db a5 --collection roads --type csv --headerline --file /files/AADF-data-minor-roads.csv SH

to import the data.

Package the box.

Distribute the box.

For the user, a simple Vagrantfile to load the box and run a simple docker-compose YAML script to start the containers and mount the mongo db against the data volume container.

I do this using another docker container whose only purpose is to seed mongo, then exit. I suspect this is the same idea as ebaxt's, but when I was looking for an answer to this, I just wanted to see a quick-and-dirty, yet straightforward, example. So here is mine:

docker-compose.yml

mongodb:
image: mongo
ports:
- "27017:27017"


mongo-seed:
build: ./mongo-seed
depends_on:
- mongodb


# my webserver which uses mongo (not shown in example)
webserver:
build: ./webserver
ports:
- "80:80"
depends_on:
- mongodb

mongo-seed/Dockerfile

FROM mongo


COPY init.json /init.json
CMD mongoimport --host mongodb --db reach-engine --collection MyDummyCollection --type json --file /init.json --jsonArray

mongo-seed/init.json

[
{
"name": "Joe Smith",
"email": "jsmith@gmail.com",
"age": 40,
"admin": false
},
{
"name": "Jen Ford",
"email": "jford@gmail.com",
"age": 45,
"admin": true
}
]

You can use this image that provides docker container for many jobs ( import, export , dump )

Look at the example using docker-compose

You can use Mongo Seeding Docker image.

Why?

  • You have the Docker image ready to go
  • You are not tied to JSON files - JavaScript and TypeScript files are supported as well (including optional model validation with TypeScript)

Example usage with Docker Compose:

version: '3'
services:
database:
image: 'mongo:3.4.10'
ports:
- '27017:27017'
api:
build: ./api/
command: npm run dev
volumes:
- ./api/src/:/app/src/
ports:
- '3000:3000'
- '9229:9229'
links:
- database
depends_on:
- database
- data_import
environment:
- &dbName DB_NAME=dbname
- &dbPort DB_PORT=27017
- &dbHost DB_HOST=database
data_import:
image: 'pkosiec/mongo-seeding:3.0.0'
environment:
- DROP_DATABASE=true
- REPLACE_ID=true
- *dbName
- *dbPort
- *dbHost
volumes:
- ./data-import/dev/:/data-import/dev/
working_dir: /data-import/dev/data/
links:
- database
depends_on:
- database

Disclaimer: I am the author of this library.

I have found useful to use Docker Custom Images and using volumes, instead of creating another container for seeding.

File Structure

.
├── docker-compose.yml
├── mongo
│   ├── data
│   ├── Dockerfile
│   └── init-db.d
│       └── seed.js

Every File location mentioned in Dockerfile/docker-compose.yml, is relative to location of docker-compose.yml

DOCKERFILE

FROM mongo:3.6


COPY ./init-db.d/seed.js /docker-entrypoint-initdb.d

docker-compose.yml

version: '3'


services:
db:
build: ./mongo
restart: always
volumes:
- ./mongo/data:/data/db #Helps to store MongoDB data in `./mongo/data`
environment:
MONGO_INITDB_ROOT_USERNAME: \{\{USERNAME}}
MONGO_INITDB_ROOT_PASSWORD: \{\{PWD}}
MONGO_INITDB_DATABASE: \{\{DBNAME}}

seed.js

// Since Seeding in Mongo is done in alphabetical order... It's is important to keep
// file names alphabetically ordered, if multiple files are to be run.


db.test.drop();
db.test.insertMany([
{
_id: 1,
name: 'Tensor',
age: 6
},
{
_id: 2,
name: 'Flow',
age: 10
}
])

docker-entrypoint-initdb.d can be used for creating different users and mongodb administration related stuffs, just create an alphabetical ordered named js-script to createUser etc...

For more details on how to customize MongoDB Docker service, read this

Also, it is good to keep your passwords and usernames secure from Public, DO NOT push credentials on public git, instead use Docker Secrets. Also read this Tutorial on Secrets

Do note, it is not necessary to go into docker-swarm mode to use secrets. Compose Files supports secrets as well. Check this

Secrets can also be used in MongoDB Docker Services

Current answer based on @Jeff Fairley answer and updated according to new Docker docs

docker-compose.yml

version: "3.5"


services:
mongo:
container_name: mongo_dev
image: mongo:latest
ports:
- 27017:27017
networks:
- dev


mongo_seed:
container_name: mongo_seed
build: .
networks:
- dev
depends_on:
- mongo


networks:
dev:
name: dev
driver: bridge

Dockerfile

FROM mongo:latest
COPY elements.json /elements.json
CMD mongoimport --host mongo --db mendeleev --collection elements --drop --file /elements.json --jsonArray

You probably need to rebuild current images.

Here is the working database seed mongodb docker compose use the below command to seed the database Dockerfile

FROM mongo:3.6.21


COPY init.json /init.json


CMD mongoimport --uri mongodb://mongodb:27017/testdb --collection users --type json --file /init.json --jsonArray

docker-compose.yml

 version: "3.7"
services:
mongodb:
container_name: mongodb
image: mongo:3.6.21
environment:
- MONGO_INITDB_DATABASE=testdb
volumes:
- ./data:/data/db
ports:
- "27017:27017"
    

mongo_seed:
build: ./db
depends_on:
- mongodb