J'essaie de distribuer un ensemble d'applications connectées s'exécutant dans plusieurs conteneurs liés, y compris une base de données mongo, nécessaire pour:
Idéalement, les données seront également conservées dans un conteneur de volume de données lié.
Je peux obtenir les données dans le conteneur mongo
à l'aide d'une instance de base mongo
qui ne monte aucun volume (image dockerhub: psychemedia/mongo_nomount
- il s'agit essentiellement du fichier Dockerfile de base sans instruction VOLUME /data/db
) et d'une config Dockerfile
suivant les lignes suivantes:
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
où ./testdata.csv
est dans le même répertoire (./mongo-with-data
) que le fichier Docker.
Mon fichier de configuration docker-compose comprend les éléments suivants:
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
Chaque fois que j'essaie de monter un VOLUME, il semble que les données d'origine conservées - qui sont stockées dans /data/db
- soient supprimées. J'imagine que lorsqu'un volume est monté sur /data/db
, il remplace ce qui existe actuellement.
Cela dit, le docker userguide suggère que: Les volumes sont initialisés lors de la création d’un conteneur. Si l’image de base du conteneur contient des données au point de montage spécifié, ces données existantes sont copiées dans le nouveau volume lors de l’initialisation du volume? Donc, je m'attendais à ce que les données persistent si je plaçais la commande VOLUME après la commande d'ensemencement RUN
?
Alors qu'est-ce que je fais mal?
En résumé, je souhaite automatiser la création de plusieurs conteneurs liés, puis distribuer un fichier YAML Vagrantfile
/docker-compose qui lancera un ensemble d’applications liées, qui inclut une base de données mongo
préamorcée avec une -peuplé) conteneur de données persistantes.
Je le fais en utilisant un autre conteneur docker dont le seul but est de semer le mongo, puis de sortir. J'imagine que c'est la même idée que celle de ebaxt , mais lorsque je cherchais une réponse à cette question, je voulais simplement voir un exemple simple et rapide. Alors voici le mien:
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
}
]
Voici un résumé de la façon dont nous utilisons des conteneurs jetables pour nettoyer et ensemencer des images https://ardoq.com/delightful-database-seeding-with-docker/
J'ai trouvé utile d'utiliser Docker Custom Images et d'utiliser des volumes, au lieu de créer un autre conteneur pour l'ensemencement.
Structure de fichier
.
├── docker-compose.yml
├── mongo
│ ├── data
│ ├── Dockerfile
│ └── init-db.d
│ └── seed.js
Chaque emplacement de fichier mentionné dans
Dockerfile
docker-compose.yml
, EST RELATIF À L'EMPLACEMENT DEdocker-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
peut être utilisé pour créer différents utilisateurs et des éléments liés à l'administration mongodb, il suffit de créer un ordre alphabétique nommé js-script àcreateUser
etc ...
Pour plus de détails sur la personnalisation du service MongoDB Docker, lisez this
En outre, il est bon de protéger vos mots de passe et noms d'utilisateur de Public, NE PAS envoyer les informations d'identification sur public git, utilisez plutôt Secrets de Docker . Lisez également ce tutoriel sur les secrets
Notez bien qu'il n'est pas nécessaire d'entrer en mode Docker-swarm pour utiliser des secrets. Compose Files supporte également les secrets. Vérifiez this
Les secrets peuvent également être utilisés dans MongoDB Docker Services
Réponse actuelle basée sur @ Jeff Fairley answer et mise à jour en fonction des nouveaux documents 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
Besoin probable de reconstruire les images actuelles
Vous pouvez utiliser image Mongo Seeding Docker .
Pourquoi?
Exemple d'utilisation avec 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: Je suis l'auteur de cette bibliothèque.
Pour répondre à ma propre question:
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
importer les données.
Emballez la boîte.
Distribuez la boîte.
Pour l'utilisateur, un simple fichier Vagrant pour charger la boîte et exécuter un simple script YAML à composition fixe pour démarrer les conteneurs et monter la base de données mongo sur le conteneur de volume de données.
Il convient de regarder cette réponse: https://stackoverflow.com/a/42917632/5209935
L'idée de base est que l'image stock mongo a un point d'entrée spécial que vous pouvez surcharger pour fournir un script qui initialise la base de données.