How to fix "Error: The server does not support SSL connections" when trying to access database in localhost? - node.js

I am following Heroku's node.js tutorial to provision a Postgres database.
After creating a simple table and connecting to localhost:5000/db, I get an error saying "Error: The server does not support SSL connections".
I've been searching for solutions for hours but can't seem to fix it. Your help will be greatly appreciated. Thank you!

Here I provide a workaround for the question, and not the title of this post. A better answer to the post overall would probably address configuring SSL for the local machine.
I arrived here trying to resolve the problem of finishing that Heroku tutorial mentioned in the question and setting up the Postgres database to work locally as well as remotely.
const pool = new Pool({
connectionString: process.env.DATABASE_URL || 'postgresql://postgres:<your admin password>#localhost:5432/<your db name>',
ssl: process.env.DATABASE_URL ? true : false
})
My idea is to use SSL on the app I deploy but dodge SSL altogether on the local machine. By simply skipping SSL config on the local machine I am able to concentrate my efforts on developing a working app that still uses Heroku's built in SSL.
I use the Heroku environment variables to detect their environment versus my own and I select values accordingly in the code sample above. For me this has worked both locally and remotely.

This is the new form Heroku is working today in 2021, they made small corrections in the connection.
const pool = (() => {
if (process.env.NODE_ENV !== 'production') {
return new Pool({
connectionString: process.env.DATABASE_URL,
ssl: false
});
} else {
return new Pool({
connectionString: process.env.DATABASE_URL,
ssl: {
rejectUnauthorized: false
}
});
} })();
They changed a bit, using this way you can keep local and heroku available.

I had the same issue for setting up my local environment after the tutorial. Sticking to the command heroku local to start my server fixed it for me. This command is detailed in the Run the app locally section of the tutorial.
In my case I added a Express server and a client side using React + Webpack. My package.json scripts for local development look like:
"dev": "run-p dev:*",
"dev:server": "heroku local -f Procfile.dev",
"dev:webpack": "webpack --watch --config webpack.dev.js --mode development",
run-p is just from npm-run-all to run all scripts starting with dev at the same time.
The server uses the heroku local command and a specific Procfile for local development (use -f flag to do this), where I start a server locally with nodemon to watch for changes (see the Procfile.dev below).
The webpack script builds and watches for changes on the client side with React.
Procfile.dev for local development:
web: nodemon index.js
Procfile for production:
web: node --optimize_for_size --max_old_space_size=920 --gc_interval=100 index.js
Then the same code for connecting to the DB from the Provision a database section works for me:
const { Pool } = require('pg');
const pool = new Pool({
connectionString: process.env.DATABASE_URL,
ssl: {
rejectUnauthorized: false
}
});

I came here not looking for a localhost solution (I wanted to connect to my db which is online), however, this turned up as the first google result, so I'll add a solution for not localhost issues here:
Check out the .env file to duplicate the Environment variables you setup in your heroku environment; see here: https://devcenter.heroku.com/articles/heroku-local#set-up-your-local-environment-variables

const pool = new Pool({
connectionString: process.env.DATABASE_URL || 'postgresql://postgres:#localhost:5432/',
ssl: process.env.DATABASE_URL ? true : false
})
In your code, you add this snippet with the credentials and connection string details, here process.env.DATABASE_URL comes from environment file, if it is there as it will enable ssl mode, else in local without ssl it works. Make sure, you will mention env variable only for other than local. So on both environment it works.

This helped me, when I was using connectionUrl.
postgres://password:postgres#localhost:5432/database?sslmode=disable
You might have noticed I have added ?sslmode=disable at the end of
connection url.
For more information about sslmode check this out.

To fix this I had to edit the database.js file.
Path to file:
<path-to-your-strapi-project>/config/database.js
if you find something with ssl that is set to true set it to false. In my case, I used Mysql it looked like this:
ssl: env.bool('DATABASE_SSL', true)
Change it to:
ssl: env.bool('DATABASE_SSL', false)

Best solution that I found that worked only:
const client = new Client({
connectionString: productiondbLink || localdblink,
ssl: process.env.DATABASE_URL ? { rejectUnauthorized: false } : false
});
client.connect();

Related

How can I define dev & production ENV using express & mysql2?

I found some other similar answers to this, but I was not confident in my ability to comprehend and get it right, so I'm hoping to get a little validation on my approach if it's right, seeing as what i've cobbled together is from a tutorial. I've also included the requires, as I'm not actually calling express in this file (db.js) but it is used in other places:
(PS. I am deploying to Heroku, and using JawsDB as my production DB)
require("dotenv").config();
const mysql = require("mysql2");
//const { DatabaseError } = require('pg');
const pool = mysql.createPool({
host: process.env.DB_HOST,
user: process.env.DB_USER,
database: process.env.DB_NAME,
password: process.env.DB_PASSWORD,
});
and this is what i'm thinking of doing:
app.configure('production', function(){
app.locals.URLs = {
const pool = mysql.createPool({
host: process.env.DB_HOST_LOCAL,
user: process.env.DB_USER_LOCAL,
database: process.env.DB_NAME_LOCAL,
password: process.env.DB_PASSWORD_LOCAL,
}
});
app.configure('development', function(){
app.locals.URLs = {
const pool = mysql.createPool({
host: process.env.DB_HOST_JAWS,
user: process.env.DB_USER_JAWS,
database: process.env.DB_NAME_JAWS,
password: process.env.DB_PASSWORD_JAWS,
}
});
is this right, and will I need to require app = require('express')?
If you want to inject anything into express (router, middleware, configuration, template engine, etc) then you're gonna need "app". With locals you are creating a "URLs" property inside your app instance.
This is not a big deal but you could instead module.exports = pool; as an independent js module and use it regardless of Express.
About your env, be cautious no to leak production passwords into development nor a developer's local configuration into production. That said you don't need a if.. else for your configuration. I also spot you don't have an env configuration for tests...
Here in the docs the prefered way to load your vars is by preloading them.
node -r dotenv/config your_script.js
You can also customize your .env file if you enjoy .env.local .env.production .env.test approach
node -r dotenv/config your_script.js dotenv_config_path=/custom/path/to/.env
This also allows you to have multiple settings without worry of conflicts / unintended overrides or leftovers.
You could also
inject individual variables via cross-env
inject production variables via PM2

Server runs locally but crashes on Heroku

I deployed my server on Heroku but when I make any requests it returns a "500 Internal Server" error. It runs fine locally though. Could anyone help figure out what's going on?
When I check my logs this is what I'm getting.
2021-06-08T18:43:09.715406+00:00 app[web.1]: error: no pg_hba.conf entry for host "3.90.138.215", user "detmvsbueicsez", database "da9nlve42hcp91", SSL off
Repo Link: https://github.com/zcason/Restaurant-Review-Server
Live App: https://restaurant-review-phi.vercel.app/
As mentioned here on Heroku help, this indicate that there was a failed authentication attempt to the database, so the connection couldn't be established. This can happen because of different reasons.
In your case i suspect it's something related to not using ssl.
So after taking a look on the code provided in the github repo i noticed you are using knex and getting the connection string from .env
Try this :
Just add this ?ssl=true and append it to the end of DATABASE_URL in your .env file.
Edit your server.js (i didn't take a good look at the code so you need to add this ssl: { rejectUnauthorized: false } in your connection config) :
const db = knex({
client: 'pg',
connection: {
connectionString: DATABASE_URL,
ssl: { rejectUnauthorized: false }
}
});
Also make sure you're using the wright user and password and database name etc
OR Alternatively :
Run this command heroku config:set PGSSLMODE=no-verify in terminal to omit the ssl configuration object and set PGSSLMODE to no-verify

"FATAL: no pg_hba.conf entry" error from postgres using db-migrate in Node on Heroku

This is background on the same error
The difference in this situation is that the pg client is constructed via db-migrate. In the process of upgrading to Node 14, in order to resolve compiler warnings, npm packages were updated as follows:
"db-migrate": "^0.11.12",
"db-migrate-pg": "^1.2.2",
"pg": "^8.5.1",
which caused deployment to heroku to now fail with this error:
psql: FATAL: no pg_hba.conf entry for host "...", user "...", database "...", SSL off
From the background, the postgres client (pg) must be changed to establish its connection using ssl = { rejectUnauthorized: false }. However, the client is created not directly but via db-migrate.
We are not using the documented command-line form of db-migrate, but instead have a wrapper migration script. This script does not invoke the command-line db-migrate but instead calls DBMigrate.getInstance(true, options);, where those options are programmatically generated per-environment. Thus we circumvent the documented file-based configuration of db-migrate.
Per the db-migrate docs, DATABASE_URL was intended for use with heroku but that assumes a command-line invocation of db-migrate will honor the environment variable and then ignore (non .rc-) file-based configuration. Since we have the wrapper script, we instead depend on DATABASE_URL via another documented db-migrate mechanism:
Note that if the settings for an environment are represented by a single string that string will be parsed as a database URL.
Thus we use this programmatic configuration generated in our wrapper script:
const options = {
env: "your_env_name_here",
config: {
your_env_name_here: process.env.DATABASE_URL
},
};
const dbmigrate = DBMigrate.getInstance(true, options);
How do I specify the required ssl configuration through db-migrate using DATABASE_URL?
It turns out that allowing db-migrate to parse our heroku-provided DATABASE_URL was itself interfering with heroku's infrastructural choices requiring ssl = { rejectUnauthorized: false } to begin with, which cannot be provided by that URL alone. The pg-connection-string library will do this for you, and the code snippet below translates that parsed URL to db-migrate's long-form but including the necessary heroku ssl configuration.
const parse = require('pg-connection-string').parse;
const r = parse(process.env.DATABASE_URL);
const options = {
env: "your_env_name_here",
config: {
your_env_name_here: {
driver: "pg",
user: r.user,
password: r.password,
host: r.host,
database: r.database,
port: r.port,
ssl: { rejectUnauthorized: false },
},
},
};
const dbmigrate = DBMigrate.getInstance(true, options);
This re-enabled our heroku deploy using Node 14 and updated npm libraries related to postgres and db-migrate.

Deploy FeathersJS App on Heroku

I'm trying to deploy my feathersjs web app on heroku, and since feathers is simply an express wrapper I thought it was like deploy an ordinary node app. I got the "npm start" script on my package.json, I added heroku remote to my git repo and when I push heroku run "yarn install" and the "npm start" script. But just when the app start, an error occurs:
heroku logs
I can't figure out what happen, any suggestions?
Maybe I could dockerize my app, someone could help me to find the proper implementation?
Thanks everybody
It is the same as Express but the generated application will by default use feathers-configuration to pull in your application settings. From the error message it looks like you are not providing a proper NODE_ENV environment variable which has to be set to production when deploying to Heroku.
Working port of feathers-chat app to Heroku PostgreSQL via Sequelize
I got a port of the hello world https://github.com/feathersjs/feathers-chat running on Heroku right now!
source: https://github.com/cirosantilli/feathers-chat/tree/sequelize-pg
live until it breaks: https://cirosantilli-feathersjs-chat.herokuapp.com/
Key source changes
Set 'postgres' to the DATABASE_URL environment variable config/production.json:
+ "postgres": "DATABASE_URL"
Heroku also exports PORT which was also already in that file before my patch.
Pass dialiectOptions to the DB connection as per: Can't connect to heroku postgresql database from local node app with sequelize
+ const sequelize = new Sequelize(connectionString, {
+ dialect: 'postgres',
+ logging: false,
+ define: {
+ freezeTableName: true
+ },
+ dialectOptions: {
+ // https://stackoverflow.com/questions/27687546/cant-connect-to-heroku-postgresql-database-from-local-node-app-with-sequelize
+ // https://devcenter.heroku.com/articles/heroku-postgresql#connecting-in-node-js
+ // https://stackoverflow.com/questions/58965011/sequelizeconnectionerror-self-signed-certificate
+ ssl: {
+ require: true,
+ rejectUnauthorized: false
+ }
+ }
+ });
Key Heroku settings
enable the PostgreSQL Heroku add-on with:
heroku addons:create heroku-postgresql:hobby-dev-
This automatically sets the DATABASE_URL environment variable for us.
in config/production.json edit host to your correct value
in the Heroku app Settings, set the NODE_ENV environment variable to production
Bibliography:
https://github.com/feathersjs/feathers/issues/1647
try set "NODE_CONFIG_DIR" to "app/config/"

node application give proxy error when in production mode

I have a mean.js app which I've deployed to my production server.
it worked well when I had it in development mode, but since I switched it to production mode I'm getting a 502 proxy error.
the same happens whether I run it with node server.js or pm2.
I'm running on linux/debian with apache2.
I a newbie in this environment, how do I find the problem.
It turned out to be an SSL issue.
in my production.js file I commented the following:
module.exports = {
//secure: {
// ssl: false,
// privateKey: './config/sslcerts/key.pem',
// certificate: './config/sslcerts/cert.pem'
//},
...
this is of course a temp solution until the application really goes live

Resources