1

enter image description here

I'm taking a beginner docker course (https://www.youtube.com/watch?v=3c-iBn73dDE&t=4384s), which I think is very well done.

As part of the course an app is put together with a node server and js frontend, communicating with with docker containers for mongo db and mongo express for persistence.

The node app can be found at https://gitlab.com/nanuchi/techworld-js-docker-demo-app/-/blob/master/app/server.js . containing:

MongoClient.connect("mongodb://admin:password@mongodb:27017", 
function (err, client) {
if (err) throw err;

var db = client.db('user-account');
userObj['userid'] = 1;

I have the 2 docker containers running on ubuntu 20.04 on a chromebook (screenshot). When I run:

11@penguin:~/techworld-js-docker-demo-app/app$ nodejs server.js 
 app listening on port 3000!

but when I open a browser to localhost:3000 , I get:

(node:2716) DeprecationWarning: current Server Discovery and Monitoring engine is deprecated, and will be removed in a future version. To use the new Server Discover and Monitoring    pass option { useUnifiedTopology: true } to the MongoClient constructor.
/home/11/techworld-js-docker-demo-app/app/node_modules/mongodb/lib/topologies/server.js:240
        throw err;
        ^

MongoNetworkError: failed to connect to server [mongodb:27017] on first connect [MongoNetworkError: getaddrinfo EAI_AGAIN mongodb mongodb:27017]
at Pool.<anonymous> (/home/11/techworld-js-docker-demo-app/app/node_modules/mongodb/lib/core/topologies/server.js:431:11)
at Pool.emit (events.js:198:13)
at createConnection (/home/11/techworld-js-docker-demo-app/app/node_modules/mongodb/lib/core/connection/pool.js:559:14)
at connect (/home/11/techworld-js-docker-demo-app/app/node_modules/mongodb/lib/core/connection/pool.js:973:11)
at makeConnection (/home/11/techworld-js-docker-demo-app/app/node_modules/mongodb/lib/core/connection/connect.js:39:11)
at callback (/home/11/techworld-js-docker-demo-app/app/node_modules/mongodb/lib/core/connection/connect.js:261:5)
at Socket.err (/home/11/techworld-js-docker-demo-app/app/node_modules/mongodb/lib/core/connection/connect.js:286:7)
at Object.onceWrapper (events.js:286:20)
at Socket.emit (events.js:198:13)
at emitErrorNT (internal/streams/destroy.js:91:8)

What am I doing wrong?

Edit; just to be clear, I am running the node project on my local machine (from my ubuntu home directory) and I'm trying to connect to the docker mongo container as the backend. The author may have skipped over how she wanted to run the gitlab project (or else I misunderstood ), but I assumed she wanted to run it on the host machine. She may have planned to run it in a container, but as It was on gitlab rather than docker , I didn't know how to get the node project into a container ..

user1592380
  • 34,265
  • 92
  • 284
  • 515
  • just to check, are you using mongo@3.6.x ? you can go into the mongo shell to check the version by running `mongo`. – kenmistry Nov 06 '20 at 01:57
  • running 'docker exec -it 87ac1b2c5cad bash' then mongo I got version 4.4.1 – user1592380 Nov 06 '20 at 02:07
  • How did you start your mongodb instance? Looks like you are trying to use the docker internal name but connecting from outside (node process running on your host) – Andreas Jägle Nov 06 '20 at 07:10

3 Answers3

5

I just had a look at your project in Gitlab. The connection string inside your code is set up for a mongodb hostname of mongodb, which should work fine when you run both, the node process and the mongodb inside docker. In your question, you seem to be executing node from your host machine. This does not allow resolving the docker internal hostname. To check this, temporarily use localhost instead of mongodb as the hostname (using this connection string mongodb://admin:password@localhost). This will use the your host machine as target of the connection which works because you also mapped the ports in your docker-compose file that opens up the port on your host machine.

For your code to work in both scenarios (development on host and all-in-docker for prod), you can't hardcode the connection string inside the code but rather need to make it configurable. One way is using environment variables for that. See the 12factor topic on configuration for conceptual details. This is especially important when it comes to credentials, which should never end up in a git repository at all. So, one common practice is to read such configuration from the environment. With node this is as simple as reading process.env.YOUR_VAR_FOR_MONGO_HOSTNAME. Check the node docs for details. This variable then needs to be exported or passed to the invocation of node. One tool that provides some convenience here is package for that is dotenv that basically allows specifying the env in a text file for development purposes. In your all-in-docker setup, you can then specify the environment variable accordingly back to mongodb instead of localhost.

Andreas Jägle
  • 11,632
  • 3
  • 31
  • 31
  • I saw that edit after posting my answer but that's exactly the case I expected. Use localhost as mongodb hostname and you are good to go using your local node process as long as your mongodb has the port mapping set up like in the commit I referenced. – Andreas Jägle Nov 07 '20 at 16:49
  • Could you please use the connection string I recommended in my answer? I'm pretty sure this solves your issues for the local setup. If not, please let me know. – Andreas Jägle Nov 07 '20 at 16:54
  • Thank you, its working now! I now see that based on https://gitlab.com/nanuchi/techworld-js-docker-demo-app/-/tree/master readme file , I was supposed to build an image from the repo using "docker build -t my-app:1.0 . " . Do you normally git clone the repo before performing docker build ? or is there another way to turn a remote repo into a local docker image? – user1592380 Nov 07 '20 at 19:03
  • Great! Technically, if somebody pushed the image to dockerhub, you can pull it by name. But it’s always good advice to not run images you don’t know. – Andreas Jägle Nov 07 '20 at 22:43
  • can you please see my issue? https://stackoverflow.com/questions/71152255/unable-to-connect-the-mongodb-container-to-node-container-in-docker – Samar Pratap Singh Feb 17 '22 at 14:31
2

What is net bindIp value in /etc/mongod.conf?
(I'm not sure where is your config, but you can try vim /etc/mongod.conf)

If net bindIp is 127.0.0.1, you only can connect to mongodb in the localhost.
When you set the 0.0.0.0 as following, you can connect to mongodb at anywhere.

# only localhost can connect 
net:
  port: 27017
  bindIp: 127.0.0.1

# everyone can connect 
net:
  port: 27017
  bindIp: 0.0.0.0

By the way, you need to restart the mongodb after you change the config.

Jack Yu
  • 2,190
  • 1
  • 8
  • 14
0

I think you need to check Mongo URL "mongodb://admin:password@mongodb" Please refer below example there is an example for connecting MongoDB

https://www.w3schools.com/nodejs/nodejs_mongodb_find.asp

try like this

const mongoose = require('mongoose');
 let op = {
  poolSize: 10, 
  bufferMaxEntries: 0, 
  reconnectTries: 5000, 
  useNewUrlParser: true, 
  useCreateIndex: true, 
  useUnifiedTopology: true 
 }
    let db = await mongoose.connect(dbUrl + dbName, op)
Prakash Harvani
  • 1,007
  • 7
  • 18