Greg Hluska

Innovative Regina based software developer

A better apache .conf pattern to serve Django applications with Apache and mod_wsgi

Avoid LetsEncrypt errors when you serve Python with Apache and mod_wsgi

Filed under: Development, Ops, Python, Apache

I generally gravitate towards using Apache when I host Python web apps. While I understand that Nginx has some performance benefits, I’ve used Apache so much that getting a Python app running nice and fast is pretty close to muscle memory. I’m not as skilled with Nginx, so if I want better performance than I get with Apache, I have to put in way more time.

Through my time online, I’ve noticed a familiar pattern. People try to deploy Django apps on Apache with mod_wsgi, try to run certbot so they can serve their applications over https and get the error:

“Name duplicates previous WSGI daemon definition”

I’ve been trying to figure out why, then I found a tutorial hosted on a site that I usually really love. I’ve reached out to the site to ask for a correction so I have no plans on naming the site in question. (Update - I’ve tried to contact the company in question and thus far, the phrase “self flagellation” comes to mind). However, the relevant tutorial suggests that developers should place the following in /etc/apache2/sites-available/000-default.conf.

<VirtualHost *:80>
    . . .

    Alias /static /home/user/myproject/static
    <Directory /home/user/myproject/static>
        Require all granted
    </Directory>

    <Directory /home/user/myproject/myproject>
        <Files wsgi.py>
            Require all granted
        </Files>
    </Directory>

    WSGIDaemonProcess myproject python-home=/home/user/myproject/
    WSGIProcessGroup myproject
    WSGIScriptAlias / /home/user/myproject/myproject/wsgi.py

</VirtualHost>

Do you catch the problem? It’s small but jumps right out at you if you read a little bit about how certbot works.

That tutorial puts WSGIDaemonProcess, WSGIProcessGroup and WSGIScriptAlias definitions inside of a VirtualHost. When certbot tries to duplicate that information to define the VirtualHost on port 443 it errors out because you can’t create the same WSGIProcessGroup inside of two VirtualHosts!

Try this instead:

WSGIDaemonProcess myproject python-home=/home/user/myproject/
WSGIProcessGroup myproject
WSGIScriptAlias / /home/user/myproject/myproject/wsgi.py
<VirtualHost *:80>
    . . .

    Alias /static /home/user/myproject/static
    <Directory /home/user/myproject/static>
        Require all granted
    </Directory>

    <Directory /home/user/myproject/myproject>
        <Files wsgi.py>
            Require all granted
        </Files>
    </Directory>

</VirtualHost>

You won’t get the error now.

Good luck and happy deployments!!

You just finished reading A better apache .conf pattern to serve Django applications with Apache and mod_wsgi.

It was filed under: Development, Ops, Python, Apache

You can see all of Greg's articles, send him a message with any feedback or follow him on Twitter.