Deploying a Flask application with Gunicorn and Docker

Martín Lamas
Trabe
Published in
3 min readDec 23, 2019
Photo by Inês Pimentel on Unsplash

In this story, we will learn how to deploy a Flask application with Gunicorn and Docker. Also, we will discover how we can use HTTPS with free SSL/TLS Let’s Encrypt certificates.

Let’s go!

Coding our flask application

First of all, we will write a very simple flask application that we will deploy later:

The Pipfile should look like this:

Now, you can test the application running the following commands:

$ pipenv install
$ env FLASK_APP=hello.py pipenv run flask run

Getting the SSL/TLS certificates

Security is essential when we build web applications. SSL/TLS certificates are a very important part of web security, allowing secure connections over HTTPS. These certificates must be signed by a WebTrust-certified certificate authority so they can be validated by the web browsers.

Let’s Encrypt is a free, automated, and open certificate authority, run for the public’s benefit. It is a service provided by the Internet Security Research Group (ISRG). Most web browsers include this certificate authority so the certificates signed by Let’s Encrypt are validated successfully.

To get a free HTTPS certificate with Let’s encrypt we can use the certbot tool. Certbot is a free, open source software tool for automatically using Let’s Encrypt certificates on manually-administrated websites to enable HTTPS. Instructions on how to obtain a new certificate are provided on the website but, in a Debian-Based GNU/Linux distribution, we can install the tool running the following command:

$ sudo apt-get install certbot

Once installed, we can get the certificate. With the -d parameter we must set the certified domain name:

$ sudo certbot certonly -d my-server-domain-name.com -n --standalone

The tool validates the domain name spinning up a web server in the machine. That is why the machine must be the server of the web application and must be accessible through this domain name.

The certificate is saved at /etc/letsencrypt/live/my-server-domain-name.com/fullchain.pem and the key file at /etc/letsencrypt/live/my-server-domain-name.com/privkey.pem. Now, we must create a certs directory and copy into it the certificate and the key files. Be careful setting the permissions so our system user can access to them:

$ mkdir /home/martin/certs
$ sudo cp /etc/letsencrypt/live/my-server-domain-name.com/fullchain.pem /home/martin/certs/
$ sudo cp /etc/letsencrypt/live/my-server-domain-name.com/privkey.pem /home/martin/certs/
$ sudo chown martin:martin /home/martin/certs/*

Writing the Dockerfile

To write the Dockerfile we will choose the python:3.8 as base image:

The application is deployed into the image using the gunicorn WSGI HTTP Server. With the -b parameter we can setup the binding port and with the -w the number of worker processes. Also, we must setup the certificate (--certfile) and the key (--keyfile).

We execute the following command to build the docker image:

$ docker build -t sample-app .

Running the application

Once the docker image has been created, we will run a container:

$ docker run -dit --name my-sample-app -p 443:443 --mount type=bind,source=/home/martin/certs,target=/certs sample-app

Don’t forget to set the bind mount to map the certificates directory.

And that’s all! To check if the application is running we will access to the following URL in our favourite web browser: https://my-server-domain-name.com?name=Martin

Renewing the certificates

Let’s Encrypt certificates are valid for 90 days. This forces us to renew the certificates from time to time.

A quick workaround to solve this problem is to use a script and a cron task. The script could be similar to this:

Then, we could setup a cron task to run this script every 75 days, for example. Don’t forget to run this script with sudo and configure it with the NOPASSWD option.

Summing up

With Docker and Gunicorn we can deploy our flask application in an easy and quick way. We can also generate SSL/TLS certificates for free thanks to Let’s Encrypt and automate the renewal process to make our web application secure.

--

--