I made 3 docker containers from 2 images in this repo and 1 using MongoDB public image. I turned ON all three containers using sudo docker-compose -f docker-compose.yaml up
docker-compose.yaml
is:
version: '3'
services:
frontend:
image: samar080301/mern-frontend:1.0
ports:
- 3000:3000
backend:
image: samar080301/mern-backend:1.0
ports:
- 5000:5000
mongodb:
image: mongo:latest
ports:
- 27017:27017
But the MongoDB couldn’t connect with the node server and gave this error:
backend_1 | > [email protected] start /home/app
backend_1 | > node server.js
backend_1 |
backend_1 | (node:18) 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 engine, pass option { useUnifiedTopology: true } to the MongoClient constructor.
backend_1 | (Use `node --trace-deprecation ...` to show where the warning was created)
backend_1 | App running on port 5000
backend_1 | Error with the database! MongoNetworkError: failed to connect to server [localhost:27017] on first connect [Error: connect ECONNREFUSED 127.0.0.1:27017
backend_1 | at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1141:16) {
backend_1 | name: 'MongoNetworkError'
backend_1 | }]
backend_1 | at Pool.<anonymous> (/home/app/node_modules/mongodb/lib/core/topologies/server.js:438:11)
backend_1 | at Pool.emit (events.js:315:20)
backend_1 | at /home/app/node_modules/mongodb/lib/core/connection/pool.js:562:14
backend_1 | at /home/app/node_modules/mongodb/lib/core/connection/pool.js:995:11
backend_1 | at /home/app/node_modules/mongodb/lib/core/connection/connect.js:32:7
backend_1 | at callback (/home/app/node_modules/mongodb/lib/core/connection/connect.js:280:5)
backend_1 | at Socket.<anonymous> (/home/app/node_modules/mongodb/lib/core/connection/connect.js:310:7)
backend_1 | at Object.onceWrapper (events.js:422:26)
backend_1 | at Socket.emit (events.js:315:20)
backend_1 | at emitErrorNT (internal/streams/destroy.js:84:8)
backend_1 | at processTicksAndRejections (internal/process/task_queues.js:84:21)
backend_1 | (node:18) UnhandledPromiseRejectionWarning: MongoNetworkError: failed to connect to server [localhost:27017] on first connect [Error: connect ECONNREFUSED 127.0.0.1:27017
backend_1 | at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1141:16) {
backend_1 | name: 'MongoNetworkError'
backend_1 | }]
Code of backend/db.js
:
const mongoose = require('mongoose');
// Allow Promises
mongoose.Promise = global.Promise;
// Connection
mongoose.connect('mongodb://localhost:27017/db_test', { useNewUrlParser: true });
// Validation
mongoose.connection
.once('open', () => console.log('Connected to the database!'))
.on('error', err => console.log('Error with the database!', err));
Terminal Output of docker inspect mongodb
:
Terminal output after adding the mongo uri as environment variable:
backend_1 | App running on port 5000
backend_1 | (node:19) UnhandledPromiseRejectionWarning: MongooseError: The `uri` parameter to `openUri()` must be a string, got "undefined". Make sure the first parameter to `mongoose.connect()` or `mongoose.createConnection()` is a string.
backend_1 | (node:19) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
New error:
backend_1 | Error with the database! MongoNetworkError: failed to connect to server [merncrudapp_mongodb_1:27017] on first connect [Error: connect ECONNREFUSED 172.23.0.3:27017
backend_1 | at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1141:16) {
backend_1 | name: 'MongoNetworkError'
backend_1 | }]
3
Answers
Try to connect not using
localhost
but a container name. So for example, if you want to connect to MongoDB from another container (in the same docker network) you can usemongodb:27017
.It should work.
When you run docker-compose up, the following happens:
MernCrudApp
(takes the default name of the directory) is created.frontend
‘s configuration. It joins the networkMernCrudApp
under the namefrontend
.backend
‘s configuration. It joins the networkMernCrudApp
under the namebackend
.mongodb
’s configuration. It joins the networkMernCrudApp
under the namemongodb
.now if you use
mongodb://localhost:27017/db_test
to connect to the db, the node app will look for MongoDB in the backend container which you will get a connection error since it does not exist.To remedy this, change the MongoDB connection string to
mongodb://mongodb:27017/db_test
so that itAditional comments
I would recommend the following to help solve some problems you might face in the future using the current configuration.
depend_on
on the docker-compose files so that the MongoDB container starts before the backend containerModify your backend/db.js code.
Your are getting error because when you mention ‘localhost‘ in code your container is trying to connect to backend container on port 2017 which not in use.
Pro Tip –
1)If you are in same docker network then use hostname or Docker Container Name to communicate/Link with each other.
2)Never use container IP address in code if IP’s are not assign manually. Whenever you restart container it may change.