Connect NodeJS to MongoDB Droplet - node.js

So I've decided to set up my project with two droplets, a MongoDB image droplet and a NodeJS image droplet. I did so to make it easier to scale both droplets in the future, and other applications may be connecting to the DB in the future, both on Ubuntu 18.04.
I'm getting the error of:
Could not connect to the database: { MongooseServerSelectionError: connection timed out
at new MongooseServerSelectionError (/root/eternal-peace-code/node_modules/mongoose/lib/error/serverSelection.js:22:11)
at NativeConnection.Connection.openUri (/root/eternal-peace-code/node_modules/mongoose/lib/connection.js:808:32)
at Mongoose.connect (/root/eternal-peace-code/node_modules/mongoose/lib/index.js:333:15)
at Timeout.setTimeout [as _onTimeout] (/root/eternal-peace-code/app.js:60:22)
at ontimeout (timers.js:482:11)
at tryOnTimeout (timers.js:317:5)
at Timer.listOnTimeout (timers.js:277:5)
message: 'connection timed out',
name: 'MongooseServerSelectionError',
reason:
TopologyDescription {
type: 'Single',
setName: null,
maxSetVersion: null,
maxElectionId: null,
servers: Map { 'mongo_droplet_ip:27017' => [Object] },
stale: false,
compatible: true,
compatibilityError: null,
logicalSessionTimeoutMinutes: null,
heartbeatFrequencyMS: 10000,
localThresholdMS: 15,
commonWireVersion: null },
[Symbol(mongoErrorContextSymbol)]: {} }
I have set up both servers correctly (so I believe), my MongoDB has two users (both are me but different permissions, I have followed several walkthroughs and so it just happened). My /etc/mongod.conf file has been edited accordingly:
net:
port: 27017
bindIp: 127.0.0.1,mongodb_droplet_ip
security:
authorization: "enabled"
The UFW firewall has HTTPS, SSH and my NodeJS_ip:27017 enabled.
My NodeJS droplet is set up with a domain name pointing to the right IP address, letsencrypt is set up for secure connection at the domain name. The issue I have now is that I can not connect to my Mongo droplet from my NodeJS application, and I would also like to make sure that it is all done securely too.
My NodeJS connect code is using Mongoose and a variables environment file, I also have the whole connect in a timeout function as per another suggestion I saw elsewhere:
setTimeout(async () => {
console.log('Connecting to database...');
const options = {
user: process.env.DBUSER,
pass: process.env.USERPASS,
keepAlive: true,
useNewUrlParser: true,
useFindAndModify: false,
useCreateIndex: true,
useUnifiedTopology: true,
sslCA: cert,
connectTimeoutMS: 5000,
}
await mongoose.connect(process.env.LIVEDB, options)
.then(() => {
console.log('We are connected to the database');
})
.catch(err => {
console.log('Could not connect to the database: ', err);
connectWithTimeout();
});
}, 3000);
I have tried a multitude of things through both droplets but I have wasted around 4 days on getting the project to a staging/production stage so it can launch whenever and just be updated as time goes on.
If you need anything else, please do let me know.
All help would be hugely appreciated,
Thanks

I don't know the URI format you are using. But I got the same issue initially when I tried to connect my node application with Mongo instance of AWS.
Using the long URI sting with all the cluster name like this
mongoURI = 'mongodb://username:password#mongo-instance-shard-00-00-a4iv8.mongodb.net:27017,mongo-instance-shard-00-01-a4iv8.mongodb.net:27017,mongo-instance-shard-00-02-a4iv8.mongodb.net:27017/test?ssl=true&replicaSet=mongo-instance-shard-0&authSource=admin&retryWrites=true&w=majority'
Instead of something like this:
mongodb+srv://server.example.com/
This worked for me. It might help you as well.
Also, found this for digital ocean link
and mongo documentation for the connection string

Related

I am getting the following error while connecting mongodb to node.js. please solve the issue [duplicate]

I have a problem when I try to connect my app with my database with Mongoose. Already tried following solutions that I found on google:
restarting MongoDB service on windows
manually open db with cmd located on bin file of mongodb
But I can't solve it. Can anyone help me ?
//my connection
const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/notes-db-app',{
useNewUrlParser: true,
useUnifiedTopology: true
})
.then(db => console.log('DB is connected'))
.catch(err => console.log(err));
And throw's me , this error
MongooseServerSelectionError: connect ECONNREFUSED ::1:27017
at NativeConnection.Connection.openUri (C:\Users\ivan\Desktop\NodeJS\notes-app\node_modules\mongoose\lib\connection.js:797:32)
at C:\Users\ivan\Desktop\NodeJS\notes-app\node_modules\mongoose\lib\index.js:330:10 at C:\Users\ivan\Desktop\NodeJS\notes-app\node_modules\mongoose\lib\helpers\promiseOrCallback.js:32:5
at new Promise ()
at promiseOrCallback (C:\Users\ivan\Desktop\NodeJS\notes-app\node_modules\mongoose\lib\helpers\promiseOrCallback.js:31:10)
at Mongoose._promiseOrCallback (C:\Users\ivan\Desktop\NodeJS\notes-app\node_modules\mongoose\lib\index.js:1151:10)
at Mongoose.connect (C:\Users\ivan\Desktop\NodeJS\notes-app\node_modules\mongoose\lib\index.js:329:20)
at Object. (C:\Users\ivan\Desktop\NodeJS\notes-app\src\db.js:3:10)
at Module._compile (node:internal/modules/cjs/loader:1095:14)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1147:10) {
reason: TopologyDescription {
type: 'Unknown',
servers: Map(1) { 'localhost:27017' => [ServerDescription] },
stale: false,
compatible: true,
heartbeatFrequencyMS: 10000,
localThresholdMS: 15,
logicalSessionTimeoutMinutes: undefined
}
}
I try to put the port on my connection code like this
//my connection
const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:27017/notes-db-app',{
useNewUrlParser: true,
useUnifiedTopology: true
})
.then(db => console.log('DB is connected'))
.catch(err => console.log(err));
and it throw's me another error
MongooseServerSelectionError: Invalid message size: 1347703880, max allowed: 67108864
at NativeConnection.Connection.openUri (C:\Users\ivan\Desktop\NodeJS\notes-app\node_modules\mongoose\lib\connection.js:797:32)
at C:\Users\ivan\Desktop\NodeJS\notes-app\node_modules\mongoose\lib\index.js:330:10 at C:\Users\ivan\Desktop\NodeJS\notes-app\node_modules\mongoose\lib\helpers\promiseOrCallback.js:32:5
at new Promise ()
at promiseOrCallback (C:\Users\ivan\Desktop\NodeJS\notes-app\node_modules\mongoose\lib\helpers\promiseOrCallback.js:31:10)
at Mongoose._promiseOrCallback (C:\Users\ivan\Desktop\NodeJS\notes-app\node_modules\mongoose\lib\index.js:1151:10)
at Mongoose.connect (C:\Users\ivan\Desktop\NodeJS\notes-app\node_modules\mongoose\lib\index.js:329:20)
at Object. (C:\Users\ivan\Desktop\NodeJS\notes-app\src\db.js:3:10)
at Module._compile (node:internal/modules/cjs/loader:1095:14)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1147:10) {
reason: TopologyDescription {
type: 'Unknown',
servers: Map(1) { 'localhost:3000' => [ServerDescription] },
stale: false,
compatible: true,
heartbeatFrequencyMS: 10000,
localThresholdMS: 15,
logicalSessionTimeoutMinutes: undefined
}
}
If the Error states:
connect() Error :MongooseServerSelectionError: connect ECONNREFUSED ::1:27017
Then the connection to localhost is refused on the IPv6 address ::1 .
Mongoose per default uses IPv6 ..
For a quick check you can set the IPv4 address explicit:
mongoose.connect('mongodb://127.0.0.1/test')
Simply pass third parameter family:4 ie.
mongoose.connect('mongodb://localhost/notes-db-app',{
useNewUrlParser: true,
useUnifiedTopology: true,
family: 4,
})
I finally solved it.
Enabling the IPV6 that MongoDB has disabled by default. Using the following command line on CMD:
mongod --ipv6
And then try again the connection and it works!
const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/notes-db-app',{
useNewUrlParser: true,
useUnifiedTopology: true
})
.then(db => console.log('DB is connected'))
.catch(err => console.log(err));
Posted on behalf of the question asker
const uri = 'mongodb://localhost:27017/test';
const options = {
useNewUrlParser: true,
useUnifiedTopology: true,
serverSelectionTimeoutMS: 5000,
autoIndex: false, // Don't build indexes
maxPoolSize: 10, // Maintain up to 10 socket connections
serverSelectionTimeoutMS: 5000, // Keep trying to send operations for 5 seconds
socketTimeoutMS: 45000, // Close sockets after 45 seconds of inactivity
family: 4 // Use IPv4, skip trying IPv6
}
const connectWithDB = () => {
mongoose.connect(uri, options, (err, db) => {
if (err) console.error(err);
else console.log("database connection")
})
}
connectWithDB()
Probably the hostname/IP of the server to which you want to connect is not correctly set.
I'm used to see that error as:
MongooseServerSelectionError: connect ECONNREFUSED <hostname/hostIP>:<port>
and in the console log you've posted, the <hostname/hostIP> part is malformed/missing.
Example - for a mongodb server running locally on port 27017 this is the error when server is down:
MongooseServerSelectionError: connect ECONNREFUSED 127.0.0.1:27017
If you're using mongodb URI to connect to the db make sure that it looks like this
"mongodb://<hostname/hostIP>:<port>"
Problem is, the localhost alias resolves to IPv6 address ::1 instead of 127.0.0.1
However, net.ipv6 defaults to false.
The best option would be to start the MongoDB with this configuration:
net:
ipv6: true
bindIpAll: true
or
net:
ipv6: true
bindIp: localhost
Then all variants should work:
C:\>mongosh "mongodb://localhost:27017" --quiet --eval "db.getMongo()"
mongodb://localhost:27017/?directConnection=true&serverSelectionTimeoutMS=2000&appName=mongosh+1.6.0
C:\>mongosh "mongodb://127.0.0.1:27017" --quiet --eval "db.getMongo()"
mongodb://127.0.0.1:27017/?directConnection=true&serverSelectionTimeoutMS=2000&appName=mongosh+1.6.0
C:\>mongosh "mongodb://[::1]:27017" --quiet --eval "db.getMongo()"
mongodb://[::1]:27017/?directConnection=true&appName=mongosh+1.6.0
If you don't run MongoDB as a service then it would be
mongod --bind_ip_all --ipv6 <other options>
NB, I don't like configuration
net:
bindIp: <ip_address>
in my opinion this makes only sense on a computer with multiple network interfaces. Use bindIp: localhost if you need to prevent any connections from remote computer (e.g. while maintenance or when used as backend database for a web-service), otherwise use bindIpAll: true
Open your terminal and type this command: mongod
Then use your app.js to establish a connection by writing this code :
const mongoose=require("mongoose");
mongoose.connect('mongodb://localhost/notes-db-app',{
useNewUrlParser: true,
useUnifiedTopology: true,
family: 4,
})
It's done now. Simply open your mongo shell or your mongodb compass and look for whatever you have added.
I also faced the same problem those commands worked for me(Ubuntu machine)
sudo chown -R mongodb:mongodb /var/lib/mongodb
sudo chown mongodb:mongodb /tmp/mongodb-27017.sock
Then
sudo service mongod restart

Can't connect to Cosmos DB Emulator with Node.js MongoDB Driver

I'm trying to connect a dummy node.js app to a local Cosmos DB Emulator instance through MongoDB drivers. The dummy app tries to connect, and if successful tries to open a DB. I've been able to do connect with same setup in a more complex app in the past, but that failed to connect now and hence I created the new dummy app, which is failing as well to connect.
I ran the Emulator with "C:\Program Files\Azure Cosmos DB Emulator\Microsoft.Azure.Cosmos.Emulator.exe" /EnableMongoDbEndpoint. Emulator admin panel shows at https://localhost:8081/_explorer/index.html. Studio 3T for MongoDB successfully connects to localhost#localhost:10255.
I exported Emulator certificate as per instructions, copied it to project root and got its path in code with const certFilePath = path.resolve(__dirname, '../', 'documentdbemulatorcert.cer');.
I've tried connecting both with Mongo Connection String (copied from admin panel):
const connectOptions = {
useNewUrlParser: true,
useUnifiedTopology: true,
ssl: true,
sslValidate: true,
sslCA: certFilePath,
};
const client = new MongoClient(MONGODB_CONNECTION_STRING, connectOptions);
as well as with Mongo URI, username and unencoded password (again, copied from admin panel):
const connectOptions = {
auth: {
username: MONGODB_AUTH_USERNAME,
password: MONGODB_AUTH_PASSWORD_NOT_ENCODED,
},
useNewUrlParser: true,
useUnifiedTopology: true,
ssl: true,
sslValidate: true,
sslCA: certFilePath,
};
const client = new MongoClient(MONGODB_URI, connectOptions);
In any case, trying to connect with this:
try {
await client.connect();
console.log('Connection to server successful');
} catch (error) {
console.error('Connection to server failed:', error);
}
fails with this error:
Connection to server failed: MongoServerSelectionError: connect ECONNREFUSED ::1:10255
at Timeout._onTimeout (...my-project-root...\node_modules\mongodb\lib\sdam\topology.js:292:38)
at listOnTimeout (node:internal/timers:564:17)
at process.processTimers (node:internal/timers:507:7) {
reason: TopologyDescription {
type: 'Unknown',
servers: Map(1) { 'localhost:10255' => [ServerDescription] },
stale: false,
compatible: true,
heartbeatFrequencyMS: 10000,
localThresholdMS: 15,
setName: null,
maxElectionId: null,
maxSetVersion: null,
commonWireVersion: 0,
logicalSessionTimeoutMinutes: null
},
code: undefined,
[Symbol(errorLabels)]: Set(0) {}
}
I've also tried excluding useNewUrlParser, useUnifiedTopology, ssl, sslValidate, sslCA, with no effect. I've also tried setting NODE_TLS_REJECT_UNAUTHORIZED=0 before running the app: there's an additional warning about less safety, but then same error. I've tried copying connection string from Studio 3T as well, but apart from some trailing parameters they're the same as Emulator admin panel, and it fails in same way.
I've download the sample Node.js app linked in admin portal Quickstart page, which uses CosmosClient instead. It fails with basically same error:
Completed with error {"message":"request to https://localhost:8081/ failed, reason: connect ECONNREFUSED ::1:8081","type":"system","errno":"ECONNREFUSED","code":"ECONNREFUSED","headers":{"x-ms-throttle-retry-count":0,"x-ms-throttle-retry-wait-time-ms":0}}
(although Emulator was still running with /EnableMongoDbEndpoint option)
Some context info: Windows 11 x64, node 19.1.0, mongodb 4.12.1, Cosmos Emulator 2.14.9.0.
I've been through related questions here on SO and elsewhere, with no help gained. Any hint? Thanks all
As always happens (thanks SO), after posting question, the solution comes up.
Running Emulator with option /EnableMongoDbEndpoint=3.6 or /EnableMongoDbEndpoint=4.0 solves the issue. Dummy app connects successfully and opens DB as well.
Command line arguments reference is here.

Cannot Connect to a MongoDB using Node.js and Mongoose

I am trying to connect my node app to a mongoDB atlas DB.
I have followed all the steps i usually follow but for some reason it just wont connect.
My code is as below (it usually uses a .env file to store the connection string but i have simplified into a variable for testing purposes)
const mongoose = require('mongoose');
//Connect to Mongoose DB
const URI = "mongodb+srv://AdminUser:**PASSWORD**#cluster0.l0f31.mongodb.net/omegadb?retryWrites=true&w=majority"
console.log("attempting to connect to MongoDB");
mongoose.connect(URI,{useNewUrlParser: true, useUnifiedTopology:true})
.then((result)=>console.log("Connected to db"))
.catch((err) => console.log(err))
This is giving me the below error in the console:
attempting to connect to MongoDB
MongooseServerSelectionError: Could not connect to any servers in your MongoDB Atlas cluster.
One common reason is that you're trying to access the database from an IP that isn't whitelisted.
Make sure your current IP address is on your Atlas cluster's IP whitelist: https://docs.atlas.mongodb.com/security-whitelist/
at NativeConnection.Connection.openUri (C:\HTML\omega\node_modules\mongoose\lib\connection.js:824:32)
at C:\HTML\omega\node_modules\mongoose\lib\index.js:381:10
at C:\HTML\omega\node_modules\mongoose\lib\helpers\promiseOrCallback.js:41:5
at new Promise (<anonymous>)
at promiseOrCallback (C:\HTML\omega\node_modules\mongoose\lib\helpers\promiseOrCallback.js:40:10)
at Mongoose._promiseOrCallback (C:\HTML\omega\node_modules\mongoose\lib\index.js:1234:10)
at Mongoose.connect (C:\HTML\omega\node_modules\mongoose\lib\index.js:380:20)
at Object.<anonymous> (C:\HTML\omega\app.js:20:16)
at Module._compile (node:internal/modules/cjs/loader:1126:14)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1180:10) {
reason: TopologyDescription {
type: 'ReplicaSetNoPrimary',
servers: Map(3) {
'cluster0-shard-00-00.l0f31.mongodb.net:27017' => [ServerDescription],
'cluster0-shard-00-01.l0f31.mongodb.net:27017' => [ServerDescription],
'cluster0-shard-00-02.l0f31.mongodb.net:27017' => [ServerDescription]
},
stale: false,
compatible: true,
heartbeatFrequencyMS: 10000,
localThresholdMS: 15,
setName: 'atlas-4p8j1o-shard-0',
maxElectionId: null,
maxSetVersion: null,
commonWireVersion: 0,
logicalSessionTimeoutMinutes: null
},
code: undefined
}
I have checked the following, none of which seem to have helped:
My user name seems to be correct
My password is correct
The database name is correct in the connection string
I have checked that the network access in mongoDB is allowing my IP as it mentions this in the error, but it is (i actually set it to allow all IPs for testing purposes and still doesnt help)
Any ideas, i have been wracking my brain on it for hours?

How to connect to Docker replica set with node.js mongodb 4+ driver where MongoDB is set up with Docker hostnames?

I successfully set up MongoDB replica set with docker-compose using Docker hostnames db1, db2, db3. However, these hostnames are of course not available outside of Docker unless I edit e.g. /etc/hosts.
The MongoDB servers use port 27017 inside the container but are exposed on ports 27017, 27027, 27037, respectively, and MongoDB servers are started with --bind_ip_all (I also tried --bind_ip localhost,db1,127.0.0.1 etc.).
Now I want to connect a non-Docker node.js application to MongoDB.
Connecting to my local replica set in Docker worked with the node.js mongodb#^3.7.3 driver but now fails with mongodb#^4, including 4.0.0.
I'm using this snippet adapted from the MongoDB driver documentation page, adding only the useUnifiedTopology flag to be able to connect:
const { MongoClient } = require("mongodb");
// Connection URI
const uri = "mongodb://user:pass#localhost/db";
// Create a new MongoClient
const client = new MongoClient(uri, { useUnifiedTopology: true });
async function run() {
try {
// Connect the client to the server
await client.connect();
// Establish and verify connection
await client.db("admin").command({ ping: 1 });
console.log("Connected successfully to server");
} finally {
// Ensures that the client will close when you finish/error
await client.close();
}
}
run().catch(console.dir);
useUnifiedTopology seems to have disappeared with mongodb driver version 4.
I tried different single server connection strings such as only with localhost as in the example (i.e. connecting to the primary only), 127.0.0.1, with and without port spec :27017 as well as replica set connection strings with localhost:27017,localhost:27027,localhost:27037 and appended ?replicaSet=rs0 and/or specified replicaSet: "rs0", readPreference: "primary" (or "nearest" etc.) in the connection options but all fail like this:
MongoServerSelectionError: getaddrinfo ENOTFOUND db1
at Timeout._onTimeout (/dev/x/m/node_modules/mongodb/lib/sdam/topology.js:310:38)
at listOnTimeout (internal/timers.js:557:17)
at processTimers (internal/timers.js:500:7) {
reason: TopologyDescription {
type: 'ReplicaSetNoPrimary',
servers: Map(3) {
'db1:27017' => [ServerDescription],
'db2:27017' => [ServerDescription],
'db3:27017' => [ServerDescription]
},
stale: false,
compatible: true,
heartbeatFrequencyMS: 10000,
localThresholdMS: 15,
setName: 'rs0',
maxSetVersion: 2,
maxElectionId: ObjectId { [Symbol(id)]: [Buffer [Uint8Array]] },
commonWireVersion: 9,
logicalSessionTimeoutMinutes: undefined
}
}
How can I connect to a Dockerized MongoDB replica set that is using Docker-internal hostnames?
Do I really need "public" hostnames that are valid both inside and outside of Docker for this to work?
Looking at the question Connect to MongoDB Replica Set running inside Docker with Java (Windows), this seems to be an unsupported case, however, it was working with the old mongodb 3 driver.
From that question:
In conclusion, to support key features of replica sets, we require that the hostnames used in a replica set config are reachable from the client.
It seems specifying directConnection: true in the connection options makes it work, preventing server delegation / redirection:
// Connection URI
const uri = "mongodb://user:pass#localhost/db";
// Create a new MongoClient
const client = new MongoClient(uri, { directConnection: true });

Connection error between nodejs and mongodb atlas using mongoose

I am trying to build a backend app using mongodb atlas. I have followed the instruction but I got error like this
{ MongooseServerSelectionError: connect ECONNREFUSED 18.140.224.177:27017
at new MongooseServerSelectionError
...
message: 'connect ECONNREFUSED 18.140.224.177:27017',
name: 'MongooseServerSelectionError',
reason:
TopologyDescription {
type: 'ReplicaSetNoPrimary',
setName: null,
maxSetVersion: null,
maxElectionId: null,
servers:
Map {
'database-shard-00-01-ayo9w.mongodb.net:27017' => [ServerDescription],
'database-shard-00-00-ayo9w.mongodb.net:27017' => [ServerDescription],
'database-shard-00-02-ayo9w.mongodb.net:27017' => [ServerDescription]
stale: false,
compatible: true,
compatibilityError: null,
logicalSessionTimeoutMinutes: null,
heartbeatFrequencyMS: 10000,
localThresholdMS: 15,
commonWireVersion: null },
[Symbol(mongoErrorContextSymbol)]: {} }
and here is my code
const mongoose = require('mongoose');
mongoose.connect("mongodb+srv://thanh:Abcdefghijk#database-ayo9w.mongodb.net/test?retryWrites=true&w=majority",
{ useNewUrlParser: true, useUnifiedTopology: true, },
).then(() => console.log('Connected to database')).
catch(err => console.log('Error in connection', err));
My whitelist entry in mongodb atlas is 0.0.0.0/0
Change username and password with your database username and password. Check mongoDB Atlas where you have created your database and collections.
The reason for this is the internet connection. I just change my wifi connection and it works. This is the link where I get the answer
Error at connecting to MongoDb Atlas Server
Your network or hosting has port 27017 blocked, that's why you can't access server.
To test if the port is blocked you can try this on terminal on mac/linux
(curl portquiz.net:27017) or on cmd (nc -v portquiz.net 27017)
This should solve your issue.

Resources