mongodb 如何使用 docker-compose 为 mongo 数据库做种?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/31210973/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I seed a mongo database using docker-compose?
提问by psychemedia
I am trying to distribute a set of connected applications running in several linked containers that includes a mongo database that is required to:
我正在尝试分发一组在多个链接容器中运行的连接应用程序,其中包括需要的 mongo 数据库:
- be distributed containing some seed data;
- allow users to add additional data.
- 分发包含一些种子数据;
- 允许用户添加额外的数据。
Ideally the data will also be persisted in a linked data volume container.
理想情况下,数据也将保存在链接的数据卷容器中。
I can get the data into the mongo
container using a mongo
base instance that doesn't mount any volumes (dockerhub image: psychemedia/mongo_nomount
- this is essentially the base mongo Dockerfile without the VOLUME /data/db
statement) and a Dockerfile
config along the lines of:
我可以mongo
使用mongo
不挂载任何卷的基本实例(dockerhub 图像:psychemedia/mongo_nomount
-这基本上是没有该VOLUME /data/db
语句的基本 mongo Dockerfile )和一个Dockerfile
配置如下:
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
where ./testdata.csv
is in the same directory (./mongo-with-data
) as the Dockerfile.
where与 Dockerfile./testdata.csv
位于同一目录 ( ./mongo-with-data
) 中。
My docker-compose config file includes the following:
我的 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
Whenever I try to mount a VOLUME it seems as if the original seeded data - which is stored in /data/db
- is deleted. I guess that when a volume is mounted to /data/db
it replaces whatever is there currently.
每当我尝试挂载 VOLUME 时,似乎存储在其中的原始种子数据都/data/db
被删除了。我猜当一个卷安装到/data/db
它时会替换当前存在的任何内容。
That said, the docker userguidesuggests that: Volumes are initialized when a container is created. If the container's base image contains data at the specified mount point, that existing data is copied into the new volume upon volume initialization? So I expected the data to persist if I placed the VOLUME command after the seeding RUN
command?
也就是说,docker 用户指南建议:创建容器时初始化卷。如果容器的基础映像包含指定挂载点的数据,则在卷初始化时将现有数据复制到新卷中?因此,如果我在播种RUN
命令之后放置 VOLUME 命令,我希望数据保持不变?
So what am I doing wrong?
那么我做错了什么?
The long view is that I want to automate the build of several linked containers, and then distribute a Vagrantfile
/docker-compose YAML file that will fire up a set of linked apps, that includes a pre-seeded mongo
database with a (partially pre-populated) persistent data container.
从长远来看,我想自动构建多个链接的容器,然后分发一个Vagrantfile
/docker-compose YAML 文件,该文件将启动一组链接的应用程序,其中包括一个预先植入的mongo
数据库(部分预先填充) 持久数据容器。
回答by Jeff Fairley
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 容器执行此操作,其唯一目的是播种 mongo,然后退出。我怀疑这与ebaxt的想法相同,但是当我寻找这个问题的答案时,我只想看到一个快速而肮脏但简单的例子。所以这是我的:
docker-compose.yml
docker-compose.yml
mongodb:
image: mongo
ports:
- "27017:27017"
mongo-seed:
build: ./mongo-seed
links:
- mongodb
# my webserver which uses mongo (not shown in example)
webserver:
build: ./webserver
ports:
- "80:80"
links:
- mongodb
mongo-seed/Dockerfile
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
mongo-seed/init.json
[
{
"name": "Joe Smith",
"email": "[email protected]",
"age": 40,
"admin": false
},
{
"name": "Jen Ford",
"email": "[email protected]",
"age": 45,
"admin": true
}
]
回答by Subroto
I have found useful to use Docker Custom Images and using volumes, instead of creating another container for seeding.
我发现使用 Docker 自定义图像和使用卷很有用,而不是为播种创建另一个容器。
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 ofdocker-compose.yml
Dockerfile
/ 中提到的每个文件位置docker-compose.yml
都相对于docker-compose.yml
DOCKERFILE
文件
FROM mongo:3.6
COPY ./init-db.d/seed.js /docker-entrypoint-initdb.d
docker-compose.yml
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
种子.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 tocreateUser
etc...
docker-entrypoint-initdb.d
可用于创建不同的用户和 mongodb 管理相关的东西,只需创建一个名为js-scriptcreateUser
的字母顺序来等等...
For more details on how to customize MongoDB Docker service, read this
有关如何自定义 MongoDB Docker 服务的更多详细信息,请阅读此内容
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
此外,最好将您的密码和用户名从 Public 中保密,不要在 public git 上推送凭据,而是使用Docker Secrets。另请阅读此秘密教程
Do note, it is not necessary to go into docker-swarm modeto use secrets. Compose Files supports secrets as well. Check this
请注意,没有必要进入docker-swarm 模式来使用秘密。Compose Files 也支持秘密。检查这个
Secrets can also be used in MongoDB Docker Services
Secrets 也可以用在MongoDB Docker 服务中
回答by while1pass
Current answer based on @Jeff Fairley answerand updated according to new Docker docs
当前答案基于@Jeff Fairley答案并根据新的 Docker 文档进行更新
docker-compose.yml
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
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.
您可能需要重建当前图像。
回答by ebaxt
Here is a writeup of how we're using disposable containers to clean and seed images https://blog.ardoq.com/dynamic-database-seeding-with-docker
这是我们如何使用一次性容器清洁和种子图像的文章https://blog.ardoq.com/dynamic-database-seeding-with-docker
回答by pkosiec
You can use Mongo Seeding Docker image.
您可以使用Mongo Seeding Docker 镜像。
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)
- 你已经准备好了 Docker 镜像
- 您不受 JSON 文件的束缚 - 也支持 JavaScript 和 TypeScript 文件(包括使用 TypeScript 的可选模型验证)
Example usage with Docker Compose:
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.
免责声明:我是这个库的作者。
回答by Matthew
It's well worth looking at this answer: https://stackoverflow.com/a/42917632/5209935
非常值得一看这个答案:https: //stackoverflow.com/a/42917632/5209935
The basic idea is that the stock mongo image has a special entrypoint that you can overload to provide a script that seeds the database.
基本思想是库存 mongo 图像有一个特殊的入口点,您可以重载它以提供一个脚本来为数据库提供种子。
回答by psychemedia
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:
- 简单的 YAML 文件,用于创建链接到数据卷容器的简单 mongo 容器,由 Vagrant docker compose 启动。
- 在 Vagrantfile 中,代码如下:
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
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.
对于用户来说,一个简单的 Vagrantfile 来加载盒子并运行一个简单的 docker-compose YAML 脚本来启动容器并将 mongo db 安装到数据卷容器上。