2016-07-18 8 views
0

У меня есть следующая ситуация: у меня есть одно приложение Node.js, которое использует MongoDB, так что с Docker Compose у меня могут быть два контейнера: один для приложения Node и еще один для MongoDB.Как запустить команду в контейнере с помощью Docker Compose?

Теперь приложение должно поддерживать следующую функцию: можно загрузить файл csv, который будет импортирован в Mongo, используя mongoimport.

С Узлом, работает mongoimport легко, потому что у нас есть функция exec. То есть, это было бы дело делать что-то вроде:

const exec = require('child_process').exec; 

exec('mongoimport -d database -c collection --type csv file.csv', function (error, stdout, stderr) { 
    // Other stuff here... 
}); 

Единственная проблема заключается в: mongoimport не будет доступен, потому что MongoDB находится внутри другого контейнера, чем приложение Node!

Теперь, как это можно решить? Я думал об использовании ssh through exec для запуска этого в контейнере Mongo, но я не уверен в этом.

Как я могу запустить mongoimport из приложения Node в контейнер Mongo?

+0

Вы можете установить инструменты/клиенты mongo в контейнере Node.js для использования mongoimport и указать узел MongoDB. Но похоже, что решение на основе Node без exec может быть более чистым. Отчасти зависит от того, что вы делаете с данными csv и характером этих файлов (размер, сложность и т. Д.). – ldg

+0

Я избегал решения на основе узла из-за эффективности. Я импортирую файлы с чем-то вроде 250 тысяч и более строк. С mongoimport данные были импортированы почти мгновенно, а с Node.js требуется некоторое время. Теперь, чтобы установить эти инструменты mongo, мне нужно было бы добавить некоторое утверждение 'apt-get' в файл dockerfile? – user1620696

+0

Да, если работа такая тяжелая, другой подход заключался бы в создании для нее службы, т. Е. В другом контейнере, который разделяет тома с приложением Node (так что он может получить файлы) и спецификацией сборки (Dockerfile), который включает mongoimport и небольшое приложение, которое позволяет вам общаться с приложением Node (http или pub/sub и т. д.). Эта модель хороша тем, что вы можете абстрагировать фактическую функциональность (mongoimport, что угодно) от вашего основного приложения, а также от db. – ldg

ответ

1

Я бы установил необходимый инструмент в контейнер Node.JS. Если вы не хотите, чтобы создать свой собственный образ, вы могли бы использовать этот один:

https://hub.docker.com/r/bitliner/nodejs-bower-grunt-mongodbclients/

в том числе:

  • Mongoclient-Tools
  • Node.js/Бауэр и Grunt

Если вы хотите создать собственное изображение, укажите:

FROM image:latest 

RUN apt-get install -y mongodb-clients 

и построить его с:

docker build -t node-mongoclient . 

и заменить изображение в Докер-compose.yml файл самость создал одну.

1

Если работа такая тяжелая, другой подход заключался бы в создании для нее отдельной службы, то есть другого контейнера, который разделяет тома с помощью приложения Node (так что он может получить файлы) и спецификации сборки (Dockerfile) который включает mongoimport и небольшое приложение, которое позволяет вам общаться с приложением Node (http или pub/sub и т. д.). Эта модель хороша тем, что вы можете абстрагировать фактическую функциональность (mongoimport, что угодно) от вашего основного приложения, а также от db.

Для службы http вы можете использовать Node или что-то действительно, и да, какой-то API был бы хорош. Для паба/юга вы можете использовать Redis с узлом в качестве одного примера, который был бы довольно легким. Это позволит любой из ваших служб иметь доступ к клиенту Redis для участия. Конечно, вы также можете использовать Mongo, если вам более удобно, но Redis pub/sub очень прост. В вашем случае вы должны убедиться, что файл был полностью загружен, прежде чем уведомлять ваш сервис о работе над ним.

Смежные вопросы