7

I have my node.js code where I establish mongodb connections like this: mongodb://localhost:27017/mycollection

Now, I put my server in one container and db in another container and I am able to connect to my db from the server like this: mongodb://mycontainer:27017/mycollection

I have this connection string configured in my server code/config.

Now, how do I detect whether a person is running the server in a container or not and accordingly take the connection string for the db?

If he is running it in the host machine, I want to use the first connection string with localhost and connect to the db in the host machine and if he connects through a container, I want to use the container link name to connect as mentioned in the second case.

Is there any way to do this?

Vignesh T.V.
  • 1,790
  • 3
  • 27
  • 48

2 Answers2

8

Personally, when I want to accomplish that, I set an ENV variable in the Dockerfile like the following:

ENV DATABASE_HOST db

You can have the full documentation on the Dockerfile reference.

Then, in your Node.js code source, you need to know whether the DATABASE_HOST is set or not (I can redirect you to this Stack Overflow Jayesh's post: Read environment variables in Node.js):

var dbHost = 'localhost';

if (process.env.DATABASE_HOST) {
    dbHost = process.env.DATABASE_HOST;
}

or in one line:

var dbHost = process.env.DATABASE_HOST || 'localhost';

Then, for MongoDB connection:

var mongodbConnection = 'mongodb://' + dbHost + ':27017/mycollection'

Now, when you run the container, you must link the container in the docker run command with --link <your mongodb container>:db (since db is the value set in the ENV variable).

But, you can also use the option -e DATABASE_HOST=<somthing else> (again with the docker run command) and use a MongoDB container under another name: -e DATABASE_HOST=anotherOne --link mongo:anotherOne.

And again, you can use an external MongoDB without linking any container if you want (which is not in another container maybe): -e DATABASE_HOST=www.mymongo.com.

EDIT: This solution is maybe better than just identifying if the application is run in a Docker container because with this one your code is usable anywhere.

Paul Rey
  • 1,270
  • 1
  • 15
  • 26
  • Thanks a lot. I don't know why I did not think of using an ENV for the DB host as well. Will do it this way. Thanks again.. – Vignesh T.V. Jun 01 '18 at 09:39
0

is-docker is a popular npm packages to accomplish this.

import isDocker from 'is-docker';

if (isDocker()) {
    console.log('Running inside a Docker container');
}

The purpose of me using the dependency is perhaps for those who are trying to determine which host to use on their database.

import isDocker from "is-docker";

const host = !!isDocker() ? "host.docker.internal" : env.NODE_DB_HOST;

Michael Nelles
  • 5,426
  • 8
  • 41
  • 57
  • While this works, one should think about if it is really necessary/worth adding another dependency to a project. Especially if it can be easily solved, without adding a dependency. This is true for any module you think about adding. – t.niese Aug 05 '22 at 20:13
  • 1
    Typically I would agree this package is only 429bytes and very popular. I made the post just to contribute to the community since there are programmers of all levels. https://npmtrends.com/is-docker – Michael Nelles Aug 05 '22 at 20:16
  • `Typically I would agree this package is only 429bytes and very popular.` that is not really an argument for using it. The `left-pad` module was also really popular and only a few bytes. Especially for modules that consist only of a few lines of code and just provide some convenient functions, you should think twice if it is really worth adding it to the project. – t.niese Aug 05 '22 at 20:21
  • The above cited example did not work for me in my environment. I tried this library and it immediately solved my problem. It has 20 million downloads a week perhaps it is for the same reason. – Michael Nelles Aug 05 '22 at 20:28