MongoDB on with Docker "failed to connect to server [localhost:27017] on first connect "
Andrew Henderson
I am using mongoDB with and NodeJS backend. The Problem is I am getting the following error
node:16) UnhandledPromiseRejectionWarning: MongoNetworkError: failed to connect to server [localhost:27017] on first connect [MongoNetworkError: connect ECONNREFUSED 127.0.0.1:27017]
This is my docker-compose
version: '3.4'
services: db: image: mongo:latest ports: - '27017:27017' rest-api-node: build: . ports: - '5000:5000' links: - db restart: on-failureI have tried with depends_on as well , was not working.
On backend I am mongoose as a middleware to communicate with DB. this is the part of my index.js
mongoose.Promise = global.Promise
mongoose.connect('mongodb://localhost/demo')
app.listen(port, () => console.log("live"))I have tried using promise as well , no change though. Please Help me out. Thanks in advance
complete error log
0at Pool. (/app/node_modules/mongodb-core/lib/topologies/server.js:505:11) rest-api-node_1 | at Pool.emit (events.js:180:13) rest-api-node_1 | at Connection. (/app/node_modules/mongodb-core/lib/connection/pool.js:329:12) rest-api-node_1 | at Object.onceWrapper (events.js:272:13) rest-api-node_1 | at Connection.emit (events.js:180:13) rest-api-node_1 | at Socket. (/app/node_modules/mongodb-core/lib/connection/connection.js:245:50) rest-api-node_1 | at Object.onceWrapper (events.js:272:13) rest-api-node_1 | at Socket.emit (events.js:180:13) rest-api-node_1 | at emitErrorNT (internal/streams/destroy.js:64:8) rest-api-node_1 | at process._tickCallback (internal/process/next_tick.js:178:19) rest-api-node_1 | name: 'MongoNetworkError', rest-api-node_1 |
message: 'failed to connect to server [localhost:27017] on first connect [MongoNetworkError: connect ECONNREFUSED 127.0.0.1:27017]' }
4 Answers
By default Compose sets up a single network for your app. Each container for a service joins the default network and is both reachable by other containers on that network, and discoverable by them at a hostname identical to the container name.
According to your docker-compose.yaml file you can access you mongo container on 127.0.0.1:27017 only from host machine.
In order to access it from NodeJS backend container you should use db:27017.
I have the same problem, other solutions not work for me but I did that this way
Note :
for mongo URI you must use your MongoDB service name instead 127.0.0.1 or localhost
for example, in below docker-compose file my mongo service name is mongodb-myapp and I change URI like this mongodb://mongodb-myapp:27017/myapp and it works for me
services: boilerplate-api-app: build: . environment: - MONGO_URI=mongodb://mongodb-myapp:27017/myapp volumes: - .:/app ports: - "5000:5000" depends_on: - mongodb-myapp mongodb-myapp: image: mongo ports: - "27017:27017" 0 I was also stuck on this for hours! Setting db:27017 in the connection string and restart: always on the rest-api-node makes sure that you connect to the correct IP and makes sure that the node server keeps on trying to connect to your db. This worked for me!
docker-compose.yaml
version: "3"
services: node-app: build: . ports: - "3000:3000" environment: - PORT=3000 mongo: image: mongo environment: - MONGO_INITDB_ROOT_USERNAME=imran - MONGO_INITDB_ROOT_PASSWORD=test_password volumes: - mongo-db:/data/db
volumes: mongo-db:The above code is the docker-compose.yaml file and the service name for the MongoDB is 'mongo'. You don't have to manually insert the IP address of the container. Instead of that just insert the service name in the MongoDB URI like this sample code given below:
const express = require("express");
const mongoose = require("mongoose");
const app = express();
mongoose .connect("mongodb://imran:test_password@mongo:27017/?authSource=admin") .then(() => { console.log("Successfully connected to the DB"); }) .catch((e) => { console.log(e); });
const port = process.env.PORT || 3000;
// routes
app.get("/", (req, res) => { res.send("<h1>Running on Container!</h1>");
});
app.listen(port, () => console.log(`listening on port ${port}`));