Как я засеваю базу данных mongo с помощью docker-compose?
Я пытаюсь распространять набор подключенных приложений, работающих в нескольких связанных контейнерах, который включает в себя базу данных mongo, которая требуется для:
- быть распределенным, содержащим некоторые данные семени;
- позволяют пользователям добавлять дополнительные данные.
В идеале данные также будут сохраняться в контейнере объединенных данных.
Я могу получить данные в контейнере mongo
, используя базовый экземпляр mongo
, который не монтирует никакие тома (dockerhub image: psychemedia/mongo_nomount
- это, по сути, базовый файл донгера mongo без инструкции VOLUME /data/db
), и a Dockerfile
config по строкам:
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
находится в одном каталоге (./mongo-with-data
) в качестве файла Docker.
Мой конфигурационный файл для 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 предполагает, что: Объемы инициализируются при создании контейнера. Если базовое изображение контейнера содержит данные в указанной точке монтирования, то существующие данные копируются в новый том после инициализации тома? Поэтому я ожидал, что данные будут сохраняться, если я поместил команду VOLUME после команды seeding RUN
?
Так что я делаю неправильно?
Долгий вид состоит в том, что я хочу автоматизировать сборку нескольких связанных контейнеров, а затем распространять файл YAML Vagrantfile
/docker-compose, который будет запускать набор связанных приложений, который включает в себя предварительно посеянный mongo
базы данных с (частично предварительно заполненным) постоянным контейнером данных.
Ответы
Ответ 1
Я делаю это с помощью другого контейнера докеров, единственной целью которого является семя 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": "[email protected]",
"age": 40,
"admin": false
},
{
"name": "Jen Ford",
"email": "[email protected]",
"age": 45,
"admin": true
}
]
Ответ 2
Я нашел полезным использовать пользовательские образы 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
докер-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 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, просто создайте алфавитный createUser
именем js-script для createUser
т.д.
Подробнее о том, как настроить сервис Docker MongoDB, читайте здесь
Кроме того, хорошо держать свои пароли и имена пользователей в безопасности от Public, НЕ выдвигать учетные данные в public git, вместо этого используйте Docker Secrets. Также прочитайте этот урок по секретам
Обратите внимание, что для использования секретов не нужно заходить в режим docker-swarm. Compose Files также поддерживает секреты. Проверьте это
Секреты также могут быть использованы в MongoDB Docker Services
Ответ 3
Вот описание того, как мы используем одноразовые контейнеры для очистки и заполнения изображений https://blog.ardoq.com/dynamic-database-seeding-with-docker
Ответ 4
Текущий ответ, основанный на @Jeff Fairley ответ и обновляется в соответствии с новыми документы Докер
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
Возможно, вам нужно восстановить текущие изображения.
Ответ 5
Вы можете использовать изображение Mongo Seeding Docker.
Зачем?
- У вас есть готовое изображение 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
Отказ от ответственности: я являюсь автором этой библиотеки.
Ответ 6
Стоит посмотреть на этот ответ: fooobar.com/questions/456666/...
Основная идея состоит в том, что у стокового образа монго есть специальная точка входа, которую вы можете перегрузить, чтобы предоставить скрипт, который заполняет базу данных.
Ответ 7
Чтобы ответить на мой собственный вопрос:
- простой файл YAML для создания простого контейнера mongo, связанного с контейнером тома данных, созданного при помощи допроса Vagrant.
- в 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-компоновки YAML script для запуска контейнеров и монтирования mongo db в контейнере объема данных.
Ответ 8
Вы можете использовать этот образ, который обеспечивает контейнер докеров для многих заданий (импорт, экспорт, дамп)
Посмотрите example, используя docker-compose