HowtoForge

How to run Python Scripts with Apache and mod_wsgi on Ubuntu 22.04

The Apache module mod_wsgi provides an interface for hosting Python-based web applications. It is a good choice for professional hosting systems as it provides a high-performance solution, but works equally well for small sites. Deployment of applications written with Python frameworks like Django, Web.py, Werkzug, Chery.py, TurboGears, and Flask is easy with mod_wsgi.

In this tutorial, I will show you how to install and configure mod_wsgi using the Apache web server on Ubuntu 22.04 LTS. This guide is an updated version of the Apache WSGI guide for Ubuntu 20.04 from Hitesh Jethva.

Prerequisites

Getting Started

Before starting, it is a good idea to update your system with the latest version. You can update your system with the following command:

sudo apt update -y
sudo apt upgrade -y

After updating the system, restart it to implement the changes.

Install Python programming language

By default, Python comes pre-installed on Ubuntu 22.04. in case Python is not installed yet, then you can install it with this command:

sudo apt install python3 libexpat1 -y

The screenshot below shows the output of the command when python is already installed.

Now proceed with the next step.

Install Apache web server and the mod_wsgi module

In this step, we will install the Apache web server and the mod_wsgi Python module. Execute the following command to install both applications. The dependent software packages will get installed automatically.

sudo apt install apache2 apache2-utils ssl-cert libapache2-mod-wsgi-py3 -y

Once all the packages are installed, you can proceed to the next step.

WSGI module configuration in Apache

Next, you need to create a new Python script inside Apache default web root directory to serve it via WSGI Apache module. We will use a small 'Hello World' script here for demonstration purposes.

You can create the python script with the following command:

sudo nano /var/www/html/wsgitest.py

Add the following lines:

def application(environ, start_response):
    status = '200 OK'
    output = b'Hello Howtoforge!\n'
    response_headers = [('Content-type', 'text/plain'),
                        ('Content-Length', str(len(output)))]
    start_response(status, response_headers)
    return [output]

Save and close the file. Then, change the ownership of the file to www-data with the following command:

sudo chown www-data:www-data /var/www/html/wsgitest.py
sudo chmod 775 /var/www/html/wsgitest.py

Next, edit the Apache virtual host configuration file to serve this file over HTTP protocol.

sudo nano /etc/apache2/sites-enabled/000-default.conf

Add the following line:

WSGIScriptAlias /wsgi /var/www/html/wsgitest.py

right before the line

</VirtualHost>

The complete virtual host file looks like this:

        # The ServerName directive sets the request scheme, hostname and port that
        # the server uses to identify itself. This is used when creating
        # redirection URLs. In the context of virtual hosts, the ServerName
        # specifies what hostname must appear in the request's Host: header to
        # match this virtual host. For the default virtual host (this file) this
        # value is not decisive as it is used as a last resort host regardless.
        # However, you must set it for any further virtual host explicitly.
        #ServerName www.example.com

        ServerAdmin webmaster@localhost
        DocumentRoot /var/www/html

        # Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
        # error, crit, alert, emerg.
        # It is also possible to configure the loglevel for particular
        # modules, e.g.
        #LogLevel info ssl:warn

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

        # For most configuration files from conf-available/, which are
        # enabled or disabled at a global level, it is possible to
        # include a line for only one particular virtual host. For example the
        # following line enables the CGI configuration for this host only
        # after it has been globally disabled with "a2disconf".
        #Include conf-available/serve-cgi-bin.conf

        WSGIScriptAlias /wsgi /var/www/html/wsgitest.py



# vim: syntax=apache ts=4 sw=4 sts=4 sr noet

Save changes in the text editor and close the editor. The next step is to restart the apache webserver to apply the changes.

systemctl restart apache2

Test the Python 3 WSGI script

Now Apache HTTP server is configured to serve our Python file over the HTTP protocol.

Open a web browser and enter the URL http://your-server-ip/wsgi. replace your-server-ip with the IP address of the server. You will get a white page with the words "Hello Howtoforge!".

That's all, you now have a properly configured Apache web server to run Python applications using mod_wsgi. The next step is to deploy your python web application into the directory /var/www/html/ and alter the WSGIScriptAlias line in the /etc/apache2/sites-enabled/000-default.conf file to match the start script of your application. Then restart Apache again to apply the configuration change.

Download as a virtual machine

This setup is available as a virtual machine download in ova/ovf format (compatible with VMWare and Virtualbox) for howtoforge subscribers.

Log in details for the VM

Please change all passwords on the first login.

How to run Python Scripts with Apache and mod_wsgi on Ubuntu 22.04