Running Flask and Jupyter with Let's Encrypt SSL certificate

By Symerio

Setting up an SSL certificate is nowadays a mandatory step for any web application in production. However during the development this step is sometimes postponed, for instance when running a demonstration flask web-server or a Jupyter notebook on a remote server. This can put sensitive data at risk as it is then transmitted unencrypted over the network.

In this post, we will illustrate how to quickly setup a free SSL certificate using Let's Encrypt. Here we focus mostly on Linux servers, but most of this guide is also applicable to other operating systems.

Obtaining a Let's Encrypt SSL certificate

The typical steps for obtaining a Let's Encrypt SSL certificate are,

  1. Configure the DNS of your domain to point to the IP or hostname of the server, using either CNAME or A entry.

  2. Create a folder where certificates will be stored, mkdir ~/certs/

  3. Start a web-server in this folder (this requires root access), cd ~/certs/ sudo python3 -m http.server 80 then press Ctrl+Z and enter bg to run this process in backround

  4. Go to certbot.eff.org, and in the drop-down menu select I'm using "None of the above" on <your OS>. Follow the installation instructions to install certbot, but not the "Getting started" section.

  5. Once Certbot is installed, run, sudo certbot certonly --webroot -w ~/certs/ -d example.com where example.com should be changed to your domain name.

  6. Once certificate were issued and are stored in ~/certs/, the web server can be stopped, by entering fg then Ctrl+C. We also need to make sure that the current user can read these certificates, sudo chown $USER ~/certs/*

Enabling SSL in Flask

Update your Flask application script with,

import os.path
from flask import Flask

app = Flask(__name__)

...

if __name__ == '__main__':
    app.run(
       host="0.0.0.0",
       ssl_context=(os.path.expanduser('~/certs/cert.pem'),
                    os.path.expanduser('~/certs/privkey.pem'))
    )

It is worth repeating that Flask built-in server should not be used in production, however it can be failry useful when running demonstration applications, such as for instance Dash PlotLy dashboards.

Enabling SSL in Jupyter

Simply start Jupyter with,

jupyter notebook --ip=example.com --certfile=$HOME/cert/cert.pem --keyfile $HOME/cert/privkey.pem

where example.com should be replaced with your domain name.