it-swarm.com.de

Wie kann ich eine Mongo-Datenbank mit Docker-Compose erstellen

Ich versuche, eine Reihe verbundener Anwendungen zu verteilen, die in mehreren verknüpften Containern ausgeführt werden, einschließlich einer Mongo-Datenbank, die Folgendes erfordert:

  • mit einigen Saatgutdaten verteilt werden;
  • benutzer können zusätzliche Daten hinzufügen.

Idealerweise werden die Daten auch in einem verknüpften Datenvolumencontainer gespeichert.

Ich kann die Daten mit einer mongo-Basisinstanz in den mongo-Container laden, die keine Volumes bereitstellt (dockerhub image: psychemedia/mongo_nomount - dies ist im Wesentlichen die Basis-Mongo-Docker-Datei ohne die VOLUME /data/db-Anweisung) und eine Dockerfile-Konfiguration entlang der folgenden Zeilen:

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

dabei befindet sich ./testdata.csv in demselben Verzeichnis (./mongo-with-data) wie die Docker-Datei.

Meine Docker-Compose-Konfigurationsdatei enthält Folgendes:

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

Wenn ich versuche, ein VOLUME zu mounten, scheint es, als ob die ursprünglich gesäten Daten - die in /data/db gespeichert sind - gelöscht werden. Ich vermute, wenn ein Volume an /data/db angehängt wird, ersetzt es das, was gerade da ist. 

Der docker userguide legt jedoch Folgendes nahe: Volumes werden initialisiert, wenn ein Container erstellt wird. Wenn das Basis-Image des Containers Daten am angegebenen Einhängepunkt enthält, werden diese vorhandenen Daten bei der Volume-Initialisierung in das neue Volume kopiert? Ich habe also erwartet, dass die Daten bestehen bleiben, wenn ich den Befehl VOLUME nach dem Befehl RUN gesetzt habe.

Was mache ich falsch?

Die lange Sicht ist, dass ich die Erstellung mehrerer verknüpfter Container automatisieren und dann eine Vagrantfile/docker-compose-YAML-Datei verteilen möchte, die eine Reihe verknüpfter Apps startet, die eine vorinstallierte mongo-Datenbank mit einer (teilweise vorinstallierten) Datenbank enthält persistenter Datencontainer.

47
psychemedia

Ich mache dies mit einem anderen Docker-Container, dessen einziger Zweck es ist, den Mongo zu säen und dann zu beenden. Ich vermute, dies ist die gleiche Idee wie ebaxt s, aber als ich nach einer Antwort darauf gesucht habe, wollte ich nur ein schnelles und schmutziges, aber einfaches Beispiel sehen. Also hier ist meins:

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

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": "[email protected]",
    "age": 40,
    "admin": false
  },
  {
    "name": "Jen Ford",
    "email": "[email protected]",
    "age": 45,
    "admin": true
  }
]
73
Jeff Fairley

Hier ist ein Bericht darüber, wie wir Einwegcontainer zum Reinigen und Seeding von Images verwenden. https://ardoq.com/delightful-database-seeding-with-docker/

4
ebaxt

Ich habe es als nützlich erachtet, Docker Custom Images und Volumes zu verwenden, anstatt einen anderen Container für das Seeding zu erstellen.

Dateistruktur

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

Jeder in Dockerfiledocker-compose.yml ANGEGEBENE DATEISPEICHERORT IST RELATIV ZUM SPEICHERORT VON 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 kann zum Erstellen verschiedener Benutzer und für die Verwaltung der mongodb-Verwaltung verwendet werden. Erstellen Sie einfach ein alphabetisch geordnetes js-script mit createUser etc ...

Weitere Informationen zum Anpassen des MongoDB Docker-Diensts finden Sie unter this .

Es ist auch gut, Ihre Kennwörter und Benutzernamen vor Public zu schützen. DO NOT Push-Anmeldeinformationen für public git. Verwenden Sie stattdessen Docker Secrets . Lesen Sie auch dieses Tutorial zu Geheimnissen

Beachten Sie, dass Sie nicht in den Docker-Swarm-Modus gehen müssen, um Geheimnisse zu verwenden. Dateien erstellen unterstützt auch Geheimnisse. Überprüfen Sie this

Geheimnisse können auch in MongoDB Docker Services verwendet werden.

3
Subroto

Die aktuelle Antwort basiert auf @ Jeff Fairley answer und wurde gemäß den neuen Docker-Dokumenten aktualisiert

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

Möglicherweise müssen aktuelle Bilder neu erstellt werden

1
while1pass

Sie können Mongo Seeding Docker image verwenden.

Warum?

  • Sie haben das Docker-Image bereit
  • Sie sind nicht an JSON-Dateien gebunden - JavaScript- und TypeScript-Dateien werden ebenfalls unterstützt (einschließlich der optionalen Modellprüfung mit TypeScript)

Beispiel für die Verwendung mit 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: Ich bin der Autor dieser Bibliothek.

1
pkosiec

Sie können dieses image verwenden, das Docker-Container für viele Jobs bereitstellt (Import, Export, Dump). 

Betrachten Sie das Beispiel mit Docker-Compose 

0
bwnyasse

Um meine eigene Frage zu beantworten:

  • einfache YAML-Datei zum Erstellen eines einfachen Mongo-Containers, der mit einem Datenvolumen-Container verbunden ist. Dieser wird von Vagrant Docker Compose ausgelöst.
  • code in der 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

um die Daten zu importieren.

Verpacken Sie die Box.

Verteile die Kiste.

Für den Benutzer eine einfache Vagrant-Datei, um die Box zu laden und ein einfaches YAML-Skript zum Erstellen eines Dockers auszuführen, um die Container zu starten und die Mongo-Datenbank mit dem Datenvolumencontainer zu mounten.

0
psychemedia

Es lohnt sich, diese Antwort zu lesen: https://stackoverflow.com/a/42917632/5209935

Die Grundidee ist, dass das Stock Mongo-Bild einen speziellen Eintrittspunkt hat, den Sie überladen können, um ein Skript bereitzustellen, das die Datenbank aussortiert.

0
Matthew