Setting up SSL on a Django App with Let's Encrypt - Ubuntu, Apache, and mod_wsgi


Joe Barrett - Feb. 3, 2017, 12:22 a.m.

Assuming that you are already running a Django app with Apache and mod_wsgi, this is a quick little tutorial on how to set up a free SSL with Let's Encrypt.

Hop in to your server, in this example I will be using SSH.

$ ssh your_server_address

Next, you want to update your software packages:

$ sudo apt-get update && sudo apt-get upgrade

If Apache is not yet installed:

$ sudo apt-get install apache2

SSL module activation on Ubuntu is nice and straightforward:

$ sudo a2enmod ssl
$ sudo a2ensite default-ssl.conf
$ sudo service apache2 restart

Visitors can now access your domain name via HTTPS protocol. BUT, because your server self-signed certificate is not issued by a trusted certificate authority an error alert would be displayed on their browsers.

Now, we are going to install the free Let's Encrypt client. If you don't already have git installed:

$ sudo apt-get install git

Next, choose a directory where you want to clone the Let's Encrypt git repository. In this tutorial we will use /usr/local/ directory as the installation path for Let's Encrypt.

$ cd /usr/local
$ sudo git clone

Now we are going to generate your free SSL cert for Apache:

$ cd /usr/local/letsencrypt
$ sudo ./letsencrypt-auto --apache -d -d

Agree the license, enter an email address for recovery and choose whether clients can browse your domain using both HTTP protocols (secure and insecure) or redirect all non-secure requests to HTTPS. After the installation process finishes successfully a congratulation message is displayed on your console informing you about the expiration date and how you can test the configuration.

Now you should be able to find your certificate files at /etc/letsencrypt/live directory with a simple directory listing.

You can now verify the status of your cert here, changing the link to include your domain:

By default, SSL certs issued by Let's Encrypt are only valid for 90 days. In order to renew the certificate before the expiration date you must manually run the client again using the exact flags and parameters as earlier.

$ sudo ./letsencrypt-auto --apache -d -d

The certificate renewal process can be automated to run in less than 30 days before the expiration date by using Linux schedule cron daemon.

$ sudo crontab -e

Add the following command at the end of the crontab file using one line only:

0 1 1 */2 * cd /usr/local/letsencrypt && ./letsencrypt-auto certonly --apache --renew-by-default --apache -d -d >> /var/log/ 2>&1

At this point, you may notice that your https domain is only listing out your folder structure. In order to fix this issue, we need to move your :80 virtualhost settings over to your :443 settings.

$ cd /etc/apache2/sites-available
$ sudo vi 000-default.conf

Your .conf file should look something like this:

Alias /static /var/www/html/static
<Directory /var/www/html/static>
        Require all granted

Alias /uploads /var/www/html/uploads
<Directory /var/www/html/uploads>
        Require all granted

<Directory /var/www/html/app_name>
                Require all granted

WSGIDaemonProcess app_name python-path=/var/www/html:/var/www/html/virtualenv/lib/python2.7/site-packages
WSGIProcessGroup app_name
WSGIScriptAlias / /var/www/html/app_name/

You just want to remove this from 000-default.conf and place it into your default-ssl.conf:

$ sudo vi /etc/apache2/sites-available/default-ssl.conf

Once you your django wsgi settings all moved over to your ssl conf, you need to make sure they are removed from your 000-default.conf. I reccomend using the following for your default conf. This will allow the automatic redirect from http to https.

<VirtualHost *:80>
        DocumentRoot /var/www/html

        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined

        # This is optional, in case you want to redirect people
        # from http to https automatically.
        RewriteEngine on
        RewriteCond %{HTTP_HOST} ^example\.com
        RewriteRule ^(.*)$$1 [R=permanent,L]

        RewriteCond %{HTTP_HOST} ^www\.example\.com
        RewriteRule ^(.*)$$1 [R=permanent,L]

Last but not least you will want to restart your apache server to take all the new changes:

$ sudo service apache2 restart

Now check your site again, without including https off the bat - it should redirect directly to https - and you are now secure!

blog comments powered by Disqus