This is a complete tutorial on how to get HTTPS working on localhost or any local domains.
What is this tutorial about:
- How to set up local a domain
- How to create a self-signed SSL certificate (or more accurately, TLS certificate)
- How to configure Nginx to use an SSL certificate
- How to run Nginx with HTTPS configured in a Docker container using docker-compose
I am using Linux so this tutorial is for Linux OS. If you use Windows, you can run the same commands using the Git Bash emulator or WSL (Windows Subsystem for Linux). Though I didn’t try it, some commands may not work. Anyway, the setup path is the same. Only commands may differ.
We will use Docker with docker-compose and Nginx at the end to test if HTTPS works.
Set up a local domain
You can use “localhost” as a domain name or create a local custom domain for development purposes. If you decide to continue with “localhost”, just skip this part and go to the next.
I will use “myapp.local” domain name as an example throughout the tutorial. You can use any domain you want.
To create a local domain you need to add a new record to the “hosts” file.
Open “/etc/hosts” file using “nano” or “vim” editor. In most cases, you will need to add “sudo” to have permission to edit and save the file. I am using “nano” editor in the command below.
Add a new line with a domain name you want.
This will map “myapp.local” domain (or any domain name you chose) to 127.0.0.1 IP. This IP is mapped to localhost in the same file.
Save and close the editor. Now when you start the Nginx server (i.e. if you use Docker from this tutorial), you can use myapp.local domain in the address bar in the browser.
Create Root self-signed SSL certificate
You can use a root certificate to create any number of local certificates. Place root certificate in the project folder or in any global folder to reuse it for any local project.
I created a new folder “local-root-ca” in the user’s home directory.
Run “genrsa” command in that folder to create a private RSA key.
Then create self-signed root CA (Certificate authority) certificate with the command below.
The “req” command creates a self-signed certificate for use as root CA.
You will be prompted to enter some certificate information. I used all default so just hit Enter for every prompt.
The output will look like this.
The next step is to add a self-signed root CA certificate to the trusted certificates in the browser. You will find tutorials for the Chrome and Firefox browsers below.
Add self-signed SSL certificate to the trusted in Chrome browser
I used version 90 of the Chrome browser.
Go to Settings (click three dots in the top right). Then click on the “Privacy and Security” menu on the left.
Choose the “Security” menu item.
Then scroll to the bottom and choose the “Manage Certificates” section in the “Advanced” section.
Choose the “Authority” tab and click the “Import” button.
Then choose your previously created “rootCA.pem” file.
Check at least “Trust this certificate for identifying websites” and click OK.
That’s it. Now the Chrome browser trusts your certificates we will create lately.
Add self-signed SSL certificate to the trusted in Firefox browser
I used version 88 of the Firefox browser.
Go to Preferences (click on the hamburger menu in the top right first). Then click on the “Privacy & Security” menu item on the left.
Scroll down and find the “Security” section, and the “View Certificates” button here. Click it.
Choose the “Authorities” tab and click the “Import” button. Find your previously created “rootCA.pem” file and choose it.
In the next dialog check at least “Trust this CA to identify websites”. Then click the “Ok” button.
That’s it. Now Firefox browser trusts your certificates we will create lately.
Create domain SSL certificates common configuration
Prepare config files you will use to create domain SSL certificates. This is a one-time task. You can use it for multiple local domains lately.
Create a certificate config file named “server.csr.cnf” with the content below.
Create an extension file named “v3.ext” with the content below.
We will use the environment variable “SSL_DOMAIN_TEMP” here. It will be easier to reuse this config for the different domains.
Create a domain SSL certificate
Set the domain name we want to create an SSL certificate to the environment variable “SSL_DOMAIN_TEMP”.
Then create “crt” and “key” files. Both are parts of an SSL certificate. The “crt” file is a signed SSL certificate and the “key” file is a private key to it.
Create a “key” file command.
Create a “crt” file command.
Create new folder “certificates”. It might be in the project folder if you will use Docker Compose. Or in any folder, if you use Nginx without Docker.
Then copy domain SSL certificate files (“server.crt” and “server.key”) to the new folder. File “server.csr” can be deleted.
Nginx HTTPS configuration sample
If you’re using Docker from this tutorial, you need to create an Nginx configuration file. Create a new file “default.conf” in the project folder.
Here is the basic Nginx configuration for localhost with HTTPS enabled.
If you don’t use Docker, then use this config as a base for your local Nginx configuration.
Run Nginx using Docker Compose
You can skip this part if you don’t use Docker.
Create the “docker-compose.yml” file in the project directory. We already have folder “certificates” here.
Fill docker-compose.yml with the content below.
Here we are:
- create a simple Nginx container from the lightweight Alpine image
- map 80 (HTTP) and 443 (HTTPS) ports from the container
- mount Nginx config and SSL certificate inside the Docker container
If you have another web server running, Docker can’t map ports 80 and 443. So either stop web server or change mapped ports, like “-81:80”. In this case, you will test the website using a URL with a port, i.e. http://localhost:81.
Test if localhost with HTTPS works
All steps completed. Now we can run the Docker container and check if HTTPS works.
Start Docker container. Run the command below from the project folder.
Wait for the container to start and go to the browser. Enter URL https://myapp.local or any domain you used in the configuration. You will the website has a secure connection in the browser.
Originally published at https://bogomolov.tech.