user1620696
user1620696

Reputation: 11405

How to run a command in a container using Docker Compose?

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?

Upvotes: 0

Views: 604

Answers (2)

ldg
ldg

Reputation: 9402

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.

Upvotes: 1

homelessDevOps
homelessDevOps

Reputation: 20736

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.

Upvotes: 1

Related Questions