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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 20:29:36  来源:igfitidea点击:

How do I seed a mongo database using docker-compose?

mongodbdockerdocker-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 mongocontainer using a mongobase instance that doesn't mount any volumes (dockerhub image: psychemedia/mongo_nomount- this is essentially the base mongo Dockerfile without the VOLUME /data/dbstatement) and a Dockerfileconfig 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.csvis 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/dbit 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 RUNcommand?

也就是说,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 mongodatabase 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 of docker-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.dcan be used for creating different users and mongodb administration related stuffs, just create an alphabetical ordered named js-script to createUseretc...

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 安装到数据卷容器上。

回答by bwnyasse

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

您可以使用此映像为许多作业(导入、导出、转储)提供 docker 容器

Look at the exampleusing docker-compose

查看使用 docker-compose的示例