How to handle the postgres connection when heroku changes the DATABASE_URL - node.js

On Heroku Postgres there is written:
The value of your app’s DATABASE_URL config var might change at any time. You should not rely on this value either inside or outside your Heroku app.
I'm developing a Node.js server that uses node-postgres to connect and manage the connection pool with the database.
But what happens when Heroku changes the DATABASE_URL? How should this problem be managed?

You handle this by always connecting to Postgres using whatever value DATABASE_URL has. For example, you can use this value as a connection string when you create your pool:
const connectionString = process.env.DATABASE_URL
const pool = new Pool({
connectionString: connectionString,
})
Heroku's dynos restart when their environment variables or addons are changed, which should cause your code to pick up the new database connection string when it starts back up.

Related

Why is my Heroku client not connecting to Heroku Postgres db?

I'm relatively new to Node, and especially new to moving an app from dev to production environment.
I have a Node + Express + Sequelize client app hosted on Heroku, as well as a Postgres db resource connected to the app. The client runs fine for certain routes, and I have the Postgres database in the "resources" of my app. But the client returns undefined on the first SQL query (e.g. a GET request to /books route simply returns undefined).
I have tried setting process.env.DATABASE_URL in app.js to the database URI like this:
const postgres =
"postgres://foo:bar#xxx.compute-1.amazonaws.com:5432/yyy";
process.env.DATABASE_URL = postgres;
I also tried manually changing "production" to test the production env in a development setting const env = process.env.NODE_ENV || "production".
I've read through Heroku docs and various articles, but I'm not sure why I can't access the database except during development.
What am I not understanding here?

Database stop sending data to node server after trying to deploy on heroku. I am just getting A pending promise

I developed a node app server that get data requested through a postgres (sequelize ORM) which send the data to my react nextjs app when requested.
A few days ago I tried to host the application on heroku, which is when all hell broke loose. the application stopped working. I was getting a socket hangup error. I followed the error stack trace until i think i pinpointed the error on when my server request data from my database. I realized there are no more data coming through. Therefore, I am left hanging with a pending promise. I rebuild my backend. I also went back to previous commit when it was working and the application is still not working. The front-end is working bc it is running on a different host but my backend is not receiving data from my db anymore. I have tried everything i can think of and read a bunch of article on stack overflow and Github but have not figure it out yet. Also, I can no longer seed my seed file for some reason (also return pending promise).
ANY HELP WILL BE REALLY APPRECIATED.
I figure out what was the problem. My configuration on the server side with my database was not working. Therefore, I was getting an unresolved promise which caused the application to just keep loading while waiting for the data. By changing my config file to this:
`
const Sequelize = require("sequelize");
let database = process.env.DATABASE_URL;
let sequelize = "";
process.env.DATABASE_URL
? (sequelize = new Sequelize(database))
: (sequelize = new Sequelize(database, "postgres", "", {
dialect: "postgres",
logging: false,
}));
`module.exports = sequelize;
and adding my postgres database manually on my terminal when running heroku pg:psql to see and create my data base. I was able to make the application work once deployed on Heroku.

Mongoose wont connect to MongoDB on Heroku (Works on local dev env)

I get the following error message when trying to connect my NodeJS Express app to my MongoDB server hosted on Heroku. It works fine on my local dev env.
MongoNetworkError: failed to connect to server [cluster0-shard-00-00-hl87n.mongodb.net:27017] on first connect [MongoNetworkError: connection 4 to cluster0-shard-00-00-hl87n.mongodb.net:27017 closed]
I am getting the connect string the following way.
const server = process.env.MONGODB_URI;
const database = process.env.MONGODB_DB;
const user = process.env.MONGODB_USER;
const password = process.env.MONGODB_PASSWORD;
mongoose.connect(`mongodb+srv://${user}:${password}#${server}/${database}`, { useNewUrlParser: true });
The enviroment variables are active on my Heroku instance, I confirmed this by doing heroku config, and also with a console log that correctly prints out all of the above information.
Any idea what could be pointing to this issue, Im out of trails to follow.
Mongodb Cloud requires that you Whitelist the IP that the connections are coming from. Unfourtunatly Heroku doesn't supply you with an IP address so you need to allow access from all IP addresses if you want it to work.
Incase anyone else falls upon this issue that was the fix.

Heroku Postgres add-on connection string for Nodejs app

I have a problem deploying a Nodejs app with a Postgresql database. The database comes from Heroku itself (Heroku Postgres add-on, hobby-dev). My app refused to connect to the database.
I found where the problem came from but I can't find a clean solution. And I think I could have misunderstood something (I'm new to Node and Heroku).
Heroku automatically gives me an environment variable DATABASE_CONFIG that includes the port:
postgres://username:password#hostname:port/databasename
Then, to connect with pg in my app, I use process.env.DATABASE_CONFIG as a connection string. I do something like:
const client = new Client({
connectionString: connectionString,
})
client.connect()
This fails to connect.
But if instead of using this environment variable, I cheat and change it, removing the port number from this connection string, it works.
I don't know why but the problem is that Heroku gives you this DATABASE_URL with the port included and you can't change it.
Did I do something wrong? Is there a clean solution to avoid that?
(because what I did is ugly as I hard-coded the DATABASE_CONFIG without the port directly in my code)
Thanks for your help!
First off, I would avoid using new Client() as this can lead to your connection being bottlenecked. Instead, use connection pooling. You can read a more indepth answer into why you want to do that here.
As for you direct issue, personally I have had trouble connecting to heroku postgres databases in the past, but here is a (basic) typical setup that works for me 99% of the time:
let pg = require('pg');
if (process.env.DATABASE_URL) {
pg.defaults.ssl = true;
}
// include an OR statement if you switch between a local dev db and
// a remote heroku environment
let connString = process.env.DATABASE_URL || 'postgresql://postgres:password#localhost:localpostgresport/yourlocaldbname';
const { Pool } = require('pg');
const pool = new Pool({
connectionString : connString
});
My first guess would be that it may have to do with ssl not being enabled. I know that has cause me problems in the past. Secondly, you want to make sure that you uses the process.env.DATABASE_URL, as environment variable should be set as the postgres connection string by Heroku.

NodeJS encrypted connection string to Postgres

I am learning NodeJS by building a JWT server. Basically I want to authorize users against credentials in a PostgreSQL database. I am considering node-postgres, passport, pg to connect with PostgreSQL but I have not found anyway to store my connection values encrypted. Ideally I would store them in a properties file so I can change them per environment.
Most examples I see do something like:
var pg = require('pg');
var conString = "postgres://YourUserName:YourPassword#localhost:5432/YourDatabase";
Can someone help show me how to encrypt and use my credentials so I don't have to hard code the plain values in my source?
There seem to exist npm packages for this already. See https://www.npmjs.com/package/secure-conf. Seems to fulfill your needs.
Please note, that you should also secure your Connection to the DB using SSL. See SSL for PostgreSQL connection nodejs for a Solution.
This should help.
if you use sequelize to connect postgres
const sequelize = new Sequelize("DB", usrname, password, {
host: "/var/run/postgresql",
dialect: "postgres",
});
NB: get the host string from your pgsl db might be different //

Resources