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

psy*_*dia 59 mongodb docker docker-compose

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

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

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

我可以mongo使用mongo不安装任何卷的基本实例将数据导入容器(dockerhub image: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
Run Code Online (Sandbox Code Playgroud)

where ./testdata.csv在与./mongo-with-dataDockerfile 相同的目录()中.

我的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
Run Code Online (Sandbox Code Playgroud)

每当我尝试安装VOLUME时,似乎/data/db删除了原始种子数据(存储在- 中).我想当一个卷安装到/data/db它时,它取代了当前的任何东西.

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

那么我做错了什么?

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

Jef*_*ley 86

我使用另一个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
Run Code Online (Sandbox Code Playgroud)

蒙戈种子/ Dockerfile

FROM mongo

COPY init.json /init.json
CMD mongoimport --host mongodb --db reach-engine --collection MyDummyCollection --type json --file /init.json --jsonArray
Run Code Online (Sandbox Code Playgroud)

蒙戈种子/ init.json

[
  {
    "name": "Joe Smith",
    "email": "jsmith@gmail.com",
    "age": 40,
    "admin": false
  },
  {
    "name": "Jen Ford",
    "email": "jford@gmail.com",
    "age": 45,
    "admin": true
  }
]
Run Code Online (Sandbox Code Playgroud)

  • 卡米洛:问题可能是当启动mongo-seed时,mongodb容器中的数据库尚未完全启动。我将在mongo-seed配置中放入“ depends_on:mongodb”。但是,这只会等待mongodb容器启动,而不会等待其中的实际数据库。如果数据库不可用,mongo-seed配置上的“ restart:on-failure”命令将使其重试。我已经看到它在数据库可用之前尝试了三到四次。 (6认同)
  • 我更喜欢把事情分开和简单,我发现通常给我最大的灵活性......例如......如果我想在种子文件中更改某些内容,我需要再次构建它.如果我的种子与我正在运行的mongo实例的图像相同,由于重置,我将丢失我的mongo数据.显然,我可以导出和导入,但这是更多的工作. (4认同)
  • 您是否碰巧遇到在不同运行中多次为数据库播种的问题? (2认同)

Sub*_*oto 8

我发现使用Docker自定义映像和使用卷很有用,而不是创建另一个用于播种的容器。

档案结构

.
??? docker-compose.yml
??? mongo
?   ??? data
?   ??? Dockerfile
?   ??? init-db.d
?       ??? seed.js
Run Code Online (Sandbox Code Playgroud)

Dockerfile/中提到的每个文件位置docker-compose.yml都相对于docker-compose.yml

DOCKERFILE

FROM mongo:3.6

COPY ./init-db.d/seed.js /docker-entrypoint-initdb.d
Run Code Online (Sandbox Code Playgroud)

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}}
Run Code Online (Sandbox Code Playgroud)

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
  }
])
Run Code Online (Sandbox Code Playgroud)

docker-entrypoint-initdb.d可以用于创建不同的用户和mongodb管理相关的东西,只需创建按字母顺序排列的名为js脚本的脚本即可,createUser等等。

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

另外,最好确保您的密码和用户名不受Public的影响,请勿在public git上推送凭据,而应使用Docker Secrets。另请阅读本秘密教程

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

秘密也可以在MongoDB Docker Services中使用


小智 8

当前答案基于 @Jeff Fairley答案并根据新的 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
Run Code Online (Sandbox Code Playgroud)

Dockerfile

FROM mongo:latest
COPY elements.json /elements.json
CMD mongoimport --host mongo --db mendeleev --collection elements --drop --file /elements.json --jsonArray
Run Code Online (Sandbox Code Playgroud)

您可能需要重建当前图像。