简体   繁体   中英

Connecting Heroku App to Atlas MongoDB Cloud service

To antecipate the question: do I need to get SSL support on Heroku in order to establish a connection between Heroku and Atlas MongoDB Cloud using SSL? (TSL/SSL connection is a requirement to access Atlas MongoDB Cloud service).


I am trying to connect my Heroku App, written in node.js, to a cluster hosted at Atlas MongoDB Cloud.

My current database is hosted at mLab (as a Heroku Add-on), and the MongoDB URI used to access the cluster through mongoose is (using xxx to omit confidential info):

MONGODB_URI="mongodb://xxx:xxx@xxx-a0.mlab.com:23266,xxx-a1.mlab.com:xxx/xxx?replicaSet=rs-xxx"

Now that I've migrated my data from mLab to Atlas MongoDB Cloud, I am currently accessing the cluster using the URI:

MONGODB_URI="mongodb://xxx:xxx@cluster0-shard-xxx.mongodb.net:xxx,cluster0-shard-xxx.mongodb.net:xxx,cluster0-shard-xxx.mongodb.net:xxx/xxx?replicaSet=xxx&ssl=true&authSource=admin"

When running my Heroku App locally in my machine I can access the database with no problem. I'm also able to connect to the cluster using mongo shell.

However, when running the App in Heroku, the connection cannot be established. In the Browser JS console, I get the 503 service unavailable message. In heroku, I get the error:

no primary found in replica set

I am aware that Atlas MongoDB Cloud requires SSL connection, differently from mLab. In my local machine, I suppose a self signed certificate is being used to connect successfully to the cluster.

My question is: do I need to get SSL support in Heroku in order to be able to access establish the secure connection between Heroku and MongoDB Atlas? Or the SSL suport in Heroku is only required to client/Heroku secure connection?

What I think might fix your problem

Disclaimer: I have used neither Heroku nor MongoDB Atlas but I am looking into them.

According to a Github issue I found , you will get that error message if you haven't whitelisted the server IP addresses in MongoDB Atlas.

Reading the MongoDB Atlas docs , the only way I see to do this in combination with Heroku dynos is to add 0.0.0.0/0 (ie all addresses) to your MongoDB Atlas whitelist.

Give that a try and please report back whether you can instantiate a connection.

On SSL

Trying to reply to the SSL question, I do not think that you need to enable it on Heroku based on what I read, although I am not totally sure.

If the MongoDB server performed certificate validation, the Node.js code for connecting to it would have to look like the following (taken from the Node.js driver documentation ):

var MongoClient = require('mongodb').MongoClient,
  f = require('util').format,
  fs = require('fs');

// Read the certificates
var ca = [fs.readFileSync(__dirname + "/ssl/ca.pem")];
var cert = fs.readFileSync(__dirname + "/ssl/client.pem");
var key = fs.readFileSync(__dirname + "/ssl/client.pem");

// Connect validating the returned certificates from the server
MongoClient.connect("mongodb://localhost:27017/test?ssl=true", {
  server: {
      sslValidate:true
    , sslCA:ca
    , sslKey:key
    , sslCert:cert
    , sslPass:'10gen'
  }
}, function(err, db) {
  db.close();
});

If the MongoDB server does not check for any SSL certificates, you can simply use code like the following (also taken from the Node.js driver documentation ):

var MongoClient = require('mongodb').MongoClient;

MongoClient.connect("mongodb://localhost:27017/test?ssl=true", function(err, db) {
  db.close();
});

Given that the Atlas documentation contains the following example code for connecting to it from Node.js, I think that you do not have to enable SSL on Heroku:

var MongoClient = require('mongodb').MongoClient;

var uri = "mongodb://kay:myRealPassword@mycluster0-shard-00-00-wpeiv.mongodb.net:27017,mycluster0-shard-00-01-wpeiv.mongodb.net:27017,mycluster0-shard-00-02-wpeiv.mongodb.net:27017/admin?ssl=true&replicaSet=Mycluster0-shard-0&authSource=admin";
MongoClient.connect(uri, function(err, db) {
  db.close();
});

您可以使用以下命令查找 Heroku 的所有 IP 范围:

HEROKU_REGION=eu; sudo apt -qqy install curl jq 2>/dev/null 1>/dev/null; heroku regions --json 2>/dev/null | jq ".[] | select(.name==\"$HEROKU_REGION\") | .provider.region" | (REGION=$(cat); curl -s https://ip-ranges.amazonaws.com/ip-ranges.json |  jq ".prefixes[] | select(.region==$REGION) | .ip_prefix")

还必须将 0.0.0.0/0 添加到 Mongo IP 白名单并在 Heroku 上重新部署我的应用程序才能使其最终工作(在更改 IP 之前,引发了 CORS 错误)。

very simple solution! just add to the white list IP in mongo atlas the adress "0.0.0.0/0"

it will open the mongo atlas to all the world..... so it os not for production but it helps for small tests

I solved this by installing an addon(i used Fixie Socks ) for Static IP addresses for database requests and other TCP connections. More options here: https://elements.heroku.com/addons#network

Since allowing access from anywhere is not secure and IP ranges could change, I ended up installing add-on QuotaGuard Static IP's (it provides 2 IP addresses for IP whitelist) so SOCKS5 Proxy can be used with QGTunnel .

QGTunnel should be downloaded and included in the codebase

curl https://s3.amazonaws.com/quotaguard/qgtunnel-latest.tar.gz | tar xz

Procfile should be updated

web: bin/qgtunnel npm start

Let's say you want to access a replicated MongoDB cluster using QGTunnel with 3 replicas located on the hosts: rs01.mongodb.net:52115 , rs02.mongodb.net:52115 , and rs1.mongodb.net:52115 . For this configuration, you will need to create 3 separate tunnels for each host on port 52115 in transparent mode . Once this is done, QGTunnel will alter the DNS resolution process to resolve these hostnames to the appropriate loopback address and auto-discovery for your replicated cluster should work as intended.

Login to cloud MongoDB site and go to network access click on Add IP Address and click on allowing access from anywhere would work

在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM