0

I have the following situation: I have one Node.js app which uses MongoDB so that with Docker Compose I can have two containers: one for the Node app and another one for the MongoDB.

Now, the app must suppor the following feature: one can upload a csv file which will be imported into Mongo using mongoimport.

With Node, running mongoimport is easy, because we have the exec function. That is, it would be a matter of doing something like:

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

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

The only problem is: mongoimport will not be available, because MongoDB is inside another container than the Node app!

Now how can this be solved? I thought on using ssh through exec to run this on the Mongo container, but I'm unsure about it.

How can I run the mongoimport from the Node app into the Mongo container?

5
  • You could install mongo tools/clients in the Node.js container to use mongoimport and specify the MongoDB host. But it seems like a Node-based solution without exec might be cleaner. Partly depends on what you are doing with the csv data and the nature of those files (size, complexity, etc.). Commented Jul 18, 2016 at 3:44
  • I was avoiding the Node-based solution because of efficiency. I'm importing a files with something like 250 thousands or more lines. With the mongoimport the data was imported almost instantaneously, while with Node.js it takes some time. Now, to install those mongo tools I would need to add some apt-get statement to the dockerfile right? Commented Jul 18, 2016 at 4:08
  • Yeah - if the job is that heavy, another approach would be to create a service for it, i.e., another container that shares a volume with the Node app (so it can get the files) and a build spec (Dockerfile) that includes mongoimport and a little app that allows you to communicate with the Node app (http or pub/sub, etc.). This model is nice in that you can abstract the actual functionality (mongoimport, whatever) from your main app, as well as from the db. Commented Jul 18, 2016 at 5:21
  • Thanks for the comment @Idg, I like this solution you suggest. The http way you mention would be to create a simple web api which waits for a request in a particular endpoint and on such request performs the import using the data on the volume right? Now, I've read a little about pub/sub but never had the opportunity to see it in practice, thus I'd like to understand how to do this using pub/sub. Can you tell me how would that go and how could I get started to implement this solution using it? Commented Jul 22, 2016 at 17:54
  • added as an answer including more details in response to your questions above. Commented Jul 22, 2016 at 19:19

2 Answers 2

1

I would install the required tool into my Node.JS Container. If you don't want to create your own image, you could use this one:

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

Including:

  • Mongoclient-Tools
  • Node.JS / Bower and Grunt

If you want to build your own image, include:

FROM image:latest

RUN apt-get install -y mongodb-clients

and build it with:

docker build -t node-mongoclient . 

and replace the image in your docker-compose.yml file the self created one.

Sign up to request clarification or add additional context in comments.

Comments

1

If the job is that heavy, another approach would be to create a separate service for it, i.e., another container that shares a volume with the Node app (so it can get the files) and a build spec (Dockerfile) that includes mongoimport and a little app that allows you to communicate with the Node app (http or pub/sub, etc.). This model is nice in that you can abstract the actual functionality (mongoimport, whatever) from your main app, as well as from the db.

For an http service, you can use Node or anything really, and yes some kind of API would be good. For pub/sub you could use Redis with Node as one example that would be pretty lightweight. It would allow any of your services that have access to a Redis client to participate. Of course, you can also use Mongo if you're more comfortable with it, but Redis pub/sub is very straightforward. The one thing in your case is you would want to make sure the file was fully uploaded before notifying your service to work on it.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.