This is a post about converting your local dev environments to HTTPS. I will briefly get into why you would want to do this, and show some example code for doing it in webpack devserver (for frontend) and on express (for backend).

Why?

  • Run your local environment on HTTPS to make it more similar to your production environments.
  • Certain newer web standards (WebAuth leaps to mind) require HTTPS to function at all.

How?

The easiest way I found was to use mkcert to generate the certs for me and setup a local CA on my machine. Generating certs manually isn‘t out of the wheel house of a lot of developers but there is definitely some arcane knowledge required that mkcert can help obscure for those times when you just want to get on with your life, or need to have it be an easy reproducible process to more easily onboard new engineers to a project. The main thing mkcert really helps with is creating a local CA.

Before you proceed I would recommend the readme for mkcert. On my macOS system installing, setting up and generating the first certificate was as easy as these 4 commands:

$ brew install mkcert
$ brew install nss

# Install the CA
$ mkcert -install

# Generate a certificate valid for the following hosts
$ mkcert dev.dispel.test localhost 127.0.0.1 ::1

I'm pretty sure the localhost parts can be left off, but I liked having them there since my dev environment dev.dispel.test points at localhost in my hosts file. You can also wildcard it with $ mkcert "*.dispel.test" localhost etc....

Don't forget to add the domain in your hosts file!

Aside: Top-Level-Domains (TLDs)

A lot of people use .dev  or even their real TLD (but overwritten in their hosts file) for their dev environment. I would highly recommend you migrate to one of .test .localhost .invalid or .example, since they are earmarked and will never be used for a real site.

You can read more about this here RFC 2606 - Reserved Top Level DNS Names.

Adding the certs

The $ mkcert <...> command from above will output a key and a certificate. In my case it created a certificate called dev.dispel.test+3.pem and a key dev.dispel.test+3-key.pem.

Webpack Devserver

The docs for this are pretty straightforward: DevServer | webpack.

If you are using a webpack.config add the files as follows:

module.exports = {
  //...
  devServer: {
    https: {
      key: fs.readFileSync('./dev.dispel.test+3-key.pem'),
      cert: fs.readFileSync('./dev.dispel.test+3.pem')
    }
  }
};

You could also load it in directly in the CLI.

Express

Without HTTPS

// Where "app" is the express app.
app.listen(port, () => console.log(`Listening on port: ${port}`));

With HTTPS

https.createServer({
  key: fs.readFileSync('dev.dispel.test+3-key.pem'),
  cert: fs.readFileSync('dev.dispel.test+3.pem')
}, app)
.listen(port, function () {
  console.log(`Listening (SSL) on port: ${port}`);
});

Source: I 100% borrowed the express code from Running express.js server over HTTPS | TimOnWeb but it is fairly straightforward. You need to load in the key and cert before running the server. Bim bada-bam bada-boom.