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

时间:2015-07-03 16:23:09

标签: mongodb docker docker-compose

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

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

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

我可以使用不安装任何卷的mongo基本实例将数据导入mongo容器(dockerhub image:psychemedia/mongo_nomount - 这实际上是基本的mongo没有VOLUME /data/db语句的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

其中./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

每当我尝试安装VOLUME时,似乎删除了存储在/data/db中的原始种子数据。我想当一个卷安装到/data/db时,它会替换当前的任何卷。

也就是说,docker userguide表明:在创建容器时初始化卷。如果容器的基本映像包含指定安装点的数据,则在卷初始化时将现有数据复制到新卷中?所以如果我在播种RUN命令后放置VOLUME命令,我希望数据能够持续存在吗?

那么我做错了什么?

长远来看,我希望自动构建多个链接容器,然后分发Vagrantfile / docker-compose YAML文件,该文件将启动一组链接的应用程序,其中包括预先播种的mongo数据库,带有(部分预先填充的)持久数据容器。

9 个答案:

答案 0 :(得分:77)

我使用另一个docker容器执行此操作,其唯一目的是为mongo提供种子,然后退出。我怀疑这与ebaxt的想法是一样的,但是当我在寻找答案时,我只想看到一个快速而肮脏但又直截了当的例子。所以这是我的:

<强>搬运工-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

<强>蒙戈种子/ Dockerfile

FROM mongo

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

<强>蒙戈种子/ init.json

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

答案 1 :(得分:4)

我发现使用Docker自定义映像和使用卷非常有用,而不是创建另一个种子容器。

文件结构

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

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

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可用于创建不同的用户以及与mongodb管理相关的内容,只需创建按字母顺序排序的js-script to createUser等...

有关如何自定义MongoDB Docker服务的更多详细信息,请阅读this

此外,最好确保您的密码和用户名不受公开的侵害,请勿在公共git上推送凭据,而应使用Docker Secrets。另请阅读此Tutorial on Secrets

  

请注意,不必进入 docker-swarm模式即可使用机密。撰写文件也支持秘密。选中this

秘密也可以在MongoDB Docker Services

中使用

答案 2 :(得分:3)

以下是我们如何使用一次性容器清洁和播种图像的文章https://blog.ardoq.com/dynamic-database-seeding-with-docker

答案 3 :(得分:2)

当前答案基于@Jeff Fairley answer,并根据新的Docker文档进行了更新

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

可能需要重建当前图像

答案 4 :(得分:1)

您可以使用Mongo Seeding Docker image

为什么?

  • 您已经准备好使用Docker映像
  • 您不受JSON文件的束缚-还支持JavaScript和TypeScript文件(包括使用TypeScript进行的可选模型验证)

使用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

免责声明:我是该库的作者。

答案 5 :(得分:0)

回答我自己的问题:

  • 简单的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

导入数据。

打包盒子。

分发该框。

对于用户来说,一个简单的Vagrantfile加载框并运行一个简单的docker-compose YAML脚本来启动容器并将mongo db挂载到数据卷容器。

答案 6 :(得分:0)

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

使用docker-compose

查看example

答案 7 :(得分:0)

非常值得看一下这个答案:https://stackoverflow.com/a/42917632/5209935

基本思想是,股票mongo映像具有一个特殊的入口点,您可以重载该入口点,以提供一个为数据库提供种子的脚本。

答案 8 :(得分:0)

这里是工作数据库种子 mongodb docker compose 使用下面的命令给数据库做种子 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
相关问题