Serve Local Site with SSL: ngrok + Custom Domain + Let's Encrypt + Django

Posted on Tue 27 June 2017 in Tech

You may want to create a webhook that another system will interact with but running it locally in your dev machine for faster development cycle. Some sites, for instance, require your webhook to be have valid SSL certificate (without warnings). This is where Let's Encrypt comes in because they allow you to create SSL certificates for free.


  • Install ngrok (brew install ngrok)
  • Install certbot (brew install certbot)
  • Setup django


  1. Register a hostname in ngrok Reserved Domains
  2. Add a CNAME record for hostname pointing to ngrok URL
  3. Add Let's Encrypt to Django
  4. Verify ACME challenge
  5. Run ngrok using generated certificate

1. Registering a Hostname in ngrok

You need to be in a Pro account to register your custom domain.

2. Add CNAME Record for Hostname

This is Route53's console but should work for any domain registrar.

3. Add Let's Encrypt to Django

We'll use a library called django-letsencrypt that will help us with Let's Encrypt's ACME challenge. Follow the installation process and you should be good.

4. Verify ACME Challenge

4.1 Start creating the certificate manually and follow along.

$ sudo certbot certonly --manual

4.2 When this message appears, take note of the challenge and the response strings.

Make sure your web server displays the following content at<challenge-xxxxx> before continuing:


4.3 Copy the strings to the ACME Challenge fields in Django admin.

4.4 Go back to the terminal and continue. If everything goes well, you'll see a congratulatory message. There should be other files in that directory like privkey.pem and cert.pem:

Congratulations! Your certificate and chain have been saved at

5. Run ngrok Using Generated Certificate

In my case, I had to copy the certificate and key to another location since ngrok is complaining about permissions.

$ ngrok tls -region=ap -key=/path/to/privkey.pem -crt=/path/to/cert.pem 8000

There you go! You should be able to access your custom domain via HTTPS serving content from your local machine.