There are times when you will need to have your local app reach out to a service via SSL, such as, say a Postgres Database out on AWS. If your local app is not configured to run SSL it simply wont work as SSL is likely enforced at the endpoint you’re trying to hit.

The following is the process I followed to get SSL running for my local app on OSX. This is a summary of multiple things that I found while researching / trying to resolve the issue. In the end my particular solution is comprised of bits of information from various sources.

There are many SSL tutorials all running through a range of console commands. I landed on an NPM package called “devcert-cli” which greatly reduces the number of steps.

To begin, install devcert-cli:

$ npm i devcert-cli –g

Devcert-cli will be installed globally. Run this command in in your project root to generate the needed cert and key:

$ devcert generate test.local

Where test.local will be the alias for localhost on your computer. This is necessary since SSL can only be applied to a domain, not localhost itself. Thus we are going to attach SSL to this arbitrary domain.

The caveat is that the test.local domain has no DNS records associated with it. This means that if you try to navigate to it in your browser that it wont appear. To resolve this Devcert will attempt to update your host file so that your computer will know how to resolve requests to “test.local”. The hosts file will point “test.local” to “127.0.0.1” (localhost).

Run this command to see what domains devcert has setup:

$ devcert list

“test.local” will appear.

Its worthwhile to check your host file for sanity’s sake to see if “test.local” appears:

$ cat /etc/hosts

Should show the following as part of the contents of your hosts file:

“127.0.0.1 test.local”

Perfect.

You may have noticed that a couple of files have appeared in your project root. First thing to do is to add those files to your .gitignore so that you accidentally commit them to source control.

Next you will load up those files using fs and hand them to the Express via an “ssl” object which holds the contents of the key and cert files.

Note the modules required into the file and where the “ssl” object is inserted when https.createServer is called.

const app = express()
const https = require('https');
const fs = require('fs');
const ssl = {
    key: fs.readFileSync('test.local.key'),
    cert: fs.readFileSync('test.local.cert')
}

app.get('/', (req, res) => {
  res.send('HTTPS-enabled!')
})

https.createServer(ssl, app).listen(3000, () => {
  console.log('Listening at https://test.local:3000...')
})