Hello WSGI – Python mod_wsgi on Ubuntu 12.04 LTS & Apache2

Run Python on your web server. In this article, we start with xUbuntu 12.04 LTS live CD and install the whole stack from scratch.
Mod_wsgi is the recommended way to install Django and many other web frameworks.
These instructions are not double tested on another computer yet.

Boot Live CD

Boot from xUbuntu 12.04 LTS live CD. If needed, use local keyboard layout ‘setxkbmap fi’.
If you want to use another version or distribution, it will be similar on any other Ubuntu, probably even Debian or Mint.

Install Apache

$ sudo apt-get update
$ sudo apt-get -y install apache2

Test that your Apache serves you an “It works” page on http://localhost.

Install and Configure mod_wsgi

$ sudo apt-get -y install libapache2-mod-wsgi
$ sudoedit /etc/apache2/sites-enabled/000-default

Add “WSGIScriptAlias /wsgi/ /home/xubuntu/public_wsgi/” inside “<VirtualHost *:80>”. Thus, your 000-default will look similar to this:

<VirtualHost *:80>
    WSGIScriptAlias /wsgi/ /home/xubuntu/public_wsgi/
    ServerAdmin webmaster@localhost
    # ...

Restart web daemon to activate your changes.

$ sudo service apache2 restart

You can already test your settings. When you browse to http://localhost/wsgi/hello.wsgi, Apache should look for the script on the right place. See that  /var/log/apache2/error.log reflects this:

  • Good: “[error] [client] Target WSGI script not found or unable to stat: /home/xubuntu/public_wsgi/hello.wsgi”
  • Bad: “[error] [client] File does not exist: /var/www/wsgi/hello.wsgi”

Only continue settings once log shows that Apache is looking for hello.wsgi file in public_wsgi/.

Write Hello.wsgi Python Script

$ nano /home/xubuntu/hello.wsgi
import os, sys
def application(environ, start_response):
    status = '200 OK'
    output = 'See you at terokarvinen.com!\n'
    response_headers = [('Content-type', 'text/plain'),
        ('Content-Length', str(len(output)))]
    start_response(status, response_headers)
    return [output]

Enjoy the output of our script on http://localhost/wsgi/hello.wsgi. You should get a page with just “See you at terokarvinen.com!” on it.


Your mod_wsgi works now. Write your own wsgi scripts, or use it with popular web frameworks such as Django, Flask and many others.

Troubleshooting & FAQ

Everything works perfectly, do I need to read on? No, stop here and go enjoy coding.
Invalid command ‘WSGIScriptAlias’, perhaps misspelled or defined by a module not included in the server configuration
=> ‘sudo apt-get -y install libapache2-mod-wsgi’
[error] [client] File does not exist: /var/www/wsgi/hello.wsgi
=> configure WSGIScriptAlias, see above
500 Internal Server Error
=> ‘tail /var/log/apache2/error.log’. Any mistake in Python, even typo, is just a 500 for the public. The details are only in logs for securitys sake.
Is it fast & efficient? Yes, it can serve thousands of requests per second.
$ ab -c 100 -n 1000 http://localhost/wsgi/hello.wsgi|grep -P ‘(Failed|#/sec)’
Failed requests:        0
Requests per second:    3050.13 [#/sec] (mean)

Posted in Uncategorized | Tagged , , , , , , , | 3 Comments

3 Responses to Hello WSGI – Python mod_wsgi on Ubuntu 12.04 LTS & Apache2

  1. MKG says:

    Making WSGI running under windows is pure hell. I couldn’t make it done after sever tries.
    But, under linux is ridiculously easy.
    Thanks for the helpful post. 🙂

  2. joe says:

    it gives me 403 forbidden
    You don’t have permission to access /wsgi/hello.wsgi on this server.

  3. Probably the daemon giving you HTTP status 403 Forbidden does not have linux file permission (ls -l, chmod) to read the file pointed by the URL. Outside web users never get the whole story, so check the logs (or use debug output) for the actual error message. Especially, find out which file that URL maps to.