Compile and install Python’s MOD_WSGI for Apache2 in Ubuntu 18.04

Having installed mod_wsgi a couple of times on different machines, I decided to note down the steps I took and put together a guide. There are also some solutions to some issues that you may encounter, which left me clueless for a while. If you are looking for a guide to deploying a Flask/Django project, you will have to look elsewhere (for the time being).

This is for use with python3 using Ubuntu 18.04’s shipped version. You may need to tweak this guide to point to non-standard versions of python3 that you specifically want to use.

I believe some Ubuntu versions have pre-packaged mod_wsgi installations available. However, noted in a previous blog post, apache2 may flood error logs pointing to a mismatch with either differing python3 or apache2 versions and in my view, a clean compilation ensures a tailored fit to your current system without the worry of logging and runtime errors.

Things to note:

  • I prefer to compile inside the “/opt” directory. Please amend the guide to suite your preference
  • I will refer to the current latest version of mod_wsgi (4.6.4 at time of writing). This is for illustrative purposes only, and some directory paths will be different with different versions
  • The guide is built around CLi, and assumes you are comfortable with the basics

Pre-Requisites

You will need to have installed some additional packages:

  • python3-dev  –  mainly for python3 header files for compilation
  • apache2
  • apache2-dev
  • gcc  –  *or an equivalent C compiler*

You may use apt install for all the above packages

Next, you will need to locate the latest mod_wsgi source files (found here)

Downloading

Navigate to /opt and download the latest version of mod_wsgi:

$ cd /opt
$ wget https://github.com/GrahamDumpleton/mod_wsgi/archive/4.6.4.tar.gz

Unpack the tar:

$ tar -xzf 4.6.4.tar.gz mod_wsgi-4.6.4/

Configure Make file

Change into the unpacked directory:

$ cd mod_wsgi-4.6.4/

Complete a “test” run of the configure script to so you can debug any errors:

$ ./configure

 

  • Error: “configure: error: no acceptable C compiler found in $PATH
    Solution: install a C compiler:

    $ sudo apt install gcc

 

  • Error: “Checking Apache Version.. ./configure: line 2765: apsx: command not found
    Solution: install apache2-dev

    $ sudo apt install apache2-dev

 

  • Error: “checking for python… no
    Solution: add argument to ./configure to point to python3 (global) or full path

    $ ./configure --with-python=python3

If you run configure without any errors, you’re ready to compile!

Compiling mod_wsgi

The make file is ready. Run Make:

$ make

This will now compile mod_wsgi. It should complete without error.

We finish the process by installing mod_wsgi to our apache2 installation:

$ make install

Configure Apache2

Finally, we need to configure apache2 correctly to load the mod_wsgi module. There are 2 ways we can do this:

  1. The “lazy way”:
    Add the following to the end of the apache2.conf file:
    (located: “/etc/apache2/apache2.conf“)

    LoadModule wsgi_module /usr/lib/apache2/modules/mod_wsgi.so

    Restart Apache2:

    $ sudo systemctl restart apache2

    If apache2 restarts without errors, you have successfully installed and loaded mod_wsgi!

  2. The “proper” way:
    Navigate to “/etc/apache2/mods-available“Create “mod_wsgi.conf”:

    $ sudo touch mod_wsgi.conf

     

    Add the following to” mod_wsgi.conf”:

    <IfModule mod_wsgi.c>
    </IfModule>

    For further information about the configuration options that can be included in “mod_wsgi.conf”, refer to docs : https://modwsgi.readthedocs.io/en/develop/configuration.html

    Create “mod_wsgi.load”:

    $ sudo touch mod_wsgi.load

    Add the following to “mod_wsgi.load”:

    LoadModule wsgi_module /usr/lib/apache2/modules/mod_wsgi.so

    Activate module in Apache and follow onscreen instructions:

    $ sudo a2enmod mod_wsgi

    If apache2 restarts without errors, you have successfully installed and loaded mod_wsgi!

Session issue with Flask deployment – apache2/wgsi/Flask

The flask app in question was working fine within Flask’s own development server. Whilst deploying the app, I ran into a 2 problems.

The first was a mismatch with apache2_mod_wsgi and the python3 version. It was throwing apache2 error messages of terminating threads. In order to fix this, I had to compile mod_wsgi from source, which was relatively easy from automated scripts, but had to install all of the necessary python headers and C compilers to tailor this to the system. No more errors but it seems to run indifferently nonetheless.

At first I thought the threading issue caused the sessions being randomly dropped, which didn’t happen in dev. Which leads me to the second problem.

Starting a session through the app (login), I can click on as many session related pages fine within a short space of time. If I stopped for more then 10 seconds, the session would drop and would prompt to log in… again.

After alot of debugging and hunting, I found the problem to be actually in apache2 config for the site. Within the .conf, the WSGI configuration was fine. However, the standard Apache document root folder directive was set 1 level above the app.wsgi file.

I’m not too clued up on the exact reason for this behaviour, but I think that when the Apache worker idles, there is insufficient permissions to read from the instance source (.wsgi file). This might kill the worker (& the app instance) and forget any sessions.

A relatively easy fix for a big problem.

P.s. if someone could explain this phenomenon better to me, please do so I can learn/update the post! Thanks.