Search code examples
node.jsmongodbherokupostmanmlab

How to get heroku to use environmental config for DB


Heroku identifies in logs that it is trying to reach out to a MongoDB shard I am not using (but used once). The error message says:

"failed to connect to server [swarmage-shard-00-00-ekq8j.gcp.mongodb.net:27017]"

but I have no idea why it is trying to connect to that server.

I am deploying a node.js app to heroku. Heroku is linked to my MLAB database. I can, via the mongo shell, interact with the database. When I run on a local server, postman can do all CRUD operations on the MLAB database. However, when I use the heroku webaddress in postman, I get a 503 error. The log shows a "MongoNetworkError" and a "TransientTransactionError". But the main issue, I think, is that it is trying to reach out to a Cloud Atlas shard that I am no longer running. I have no connection strings in my code; they are all set by environmental variables. I have updated and double checked that both my local system is set to the new connection strings and that heroku is configured for the new connection strings. I have no idea where heroku (or mlab? or mongodb?) is grabbing the old connection shard from.

I have tried unset configs for both heroku and the local server. I have tried to find the old instance of the shard on cluster atlas, but can't. Everything works until I try to use postman to reach out to the heroku address.

I can't find anything in the heroku docs or mongo saying anything about doing more than clicking on the connection strings and putting them in the code. I also tried putting the correct connection strings directly into the code--no change.

I figure there is a default setting somewhere that I need to change, but I have no idea where.

I don't think the code will help, but for sake of showing code (it's all up on Github)

production config:

{
  "name": "SwarmAge - Production",
  "mail": {
    "host": "prod-mail-server"
  },
  "title": "Welcome to the Swarm Age"

}

custom-environmental-variables

{
  "mail": {
    "password": "SwarmAge_password"
  },
  "jwtPrivateKey": "SwarmAge_jwtPrivateKey",
  "connectionString": "SwarmAge_db"
}

index.js

const express = require("express");
const app = express();
const winston = require("winston");

require("./startup/logging")();
require("./startup/routes")(app);
require("./startup/db")();
require("./startup/config")();
require("./startup/validation")();
require("./startup/prod")(app);
require("./startup/status")(app);

app.set("view engine", "pug");
app.set("views", "./views");

const port = process.env.PORT || 3000;
const server = app.listen(port, () =>
  winston.info(`Listening on port ${port}`)
);

module.exports = server;

start up config

const config = require("config");

module.exports = function() {
  if (!config.get("jwtPrivateKey")) {
    throw new Error("FATAL ERROR: jwtPrivateKey is not defined.");
  }
};

start up db

module.exports = function() {
  const db = config.get("connectionString");
  mongoose
    .connect(db, {
      useNewUrlParser: true,
      useFindAndModify: false
    })
    .then(() => winston.info(`Connected to ${db} . . .`));
};

from the terminal, heroku configs (to go to Heroku, where is it getting the shard from?):-------

C:\Users\tedgo\voter>heroku config

swarmage-backend-190625 Config Vars

NODE_ENV: production
SwarmAge_db: mongodb://AdminGLOC:fakopassword@ds155461.mlab.com:55461/heroku_6qxb8b19
SwarmAge_jwtPrivateKey: hidden
SwarmAge_password: not-important
jwtPrivateKey: took-this-out-as-well

my settings (to go to Cluster Atlas--this works)

SwarmAge_db=mongodb+srv://AdminGLOC:not-my-real-password@swarmage-0idyv.gcp.mongodb.net/development?retryWrites=true

And here is the error message from the logs:

cat uncaughtExceptions.log {"error":{"name":"MongoNetworkError","errorLabels":["TransientTransactionError"]},"level":"error","message":"uncaughtException: failed to connect to server [swarmage-shard-00-00-ekq8j.gcp.mongodb.net:27017] on first connect [MongoError: bad auth Authentication failed.]\nMongoNetworkError: failed to connect to server [swarmage-shard-00-00-ekq8j.gcp.mongodb.net:27017] on first connect [MongoError: bad auth Authentication failed.]\n at Pool. (C:\Users\tedgo\node_modules\mongodb-core\lib\topologies\server.js:431:11)\n at Pool.emit (events.js:189:13)\n at connect (C:\Users\tedgo\node_modules\mongodb-core\lib\connection\pool.js:557:14)\n at callback (C:\Users\tedgo\node_modules\mongodb-core\lib\connection\connect.js:109:5)\n at provider.auth.err (C:\Users\tedgo\node_modules\mongodb-core\lib\connection\connect.js:352:21)\n at _authenticateSingleConnection (C:\Users\tedgo\node_modules\mongodb-core\lib\auth\auth_provider.js:66:11)\n at sendAuthCommand (C:\Users\tedgo\node_modules\mongodb-core\lib\auth\scram.js:215:18)\n at Connection.messageHandler (C:\Users\tedgo\node_modules\mongodb-core\lib\connection\connect.js:334:5)\n at Connection.emit (events.js:189:13)\n at processMessage (C:\Users\tedgo\node_modules\mongodb-core\lib\connection\connection.js:364:10)\n at TLSSocket. (C:\Users\tedgo\node_modules\mongodb-core\lib\connection\connection.js:533:15)\n at TLSSocket.emit (events.js:189:13)\n at addChunk (_stream_readable.js:284:12)\n at readableAddChunk (_stream_readable.js:265:11)\n at TLSSocket.Readable.push (_stream_readable.js:220:10)\n at TLSWrap.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)","stack":"MongoNetworkError: failed to connect to server [swarmage-shard-00-00-ekq8j.gcp.mongodb.net:27017] on first connect [MongoError: bad auth Authentication failed.]\n at Pool. (C:\Users\tedgo\node_modules\mongodb-core\lib\topologies\server.js:431:11)\n at Pool.emit (events.js:189:13)\n at connect (C:\Users\tedgo\node_modules\mongodb-core\lib\connection\pool.js:557:14)\n at callback (C:\Users\tedgo\node_modules\mongodb-core\lib\connection\connect.js:109:5)\n at provider.auth.err (C:\Users\tedgo\node_modules\mongodb-core\lib\connection\connect.js:352:21)\n at _authenticateSingleConnection (C:\Users\tedgo\node_modules\mongodb-core\lib\auth\auth_provider.js:66:11)\n at sendAuthCommand (C:\Users\tedgo\node_modules\mongodb-core\lib\auth\sc


Solution

  • This answer comes from coder Santiago Beltram. -several issues.
    --First, the default.config file needed to hold all variables found in custom-environmental-variable. It did not. --Second, in models.supporters.js there was an error where "require('jsonwebtoken')" was written in camel case "require('jasonWebToken')". This would not require the proper program. --Third, not all dependencies appeared in the package.json file. As such heroku did not know to include them.
    After fixing the code and including the missing dependencies in package.json by using a --save flag, the program was successfully deployed to heroku.