Posts Tagged ‘ mod_wsgi

mod_wsgi on OSX

It’s been quite a while since my last words on these pages. And yes, I’m writing in english, my bad english for a number of reasons… But this is out of scope, so let’s put away the dust and start to write something (hopefully) useful :)

These days I’m experiencing Python and the web full-stack framework Django. They both are impressive, really: starting the development of a webapp is almost straightforward, if you have the time to read the really good documentation available at https://docs.djangoproject.com.

After a bit of exercise, I developed a tutorial application, and I wanted to deploy it with the Apache Web Server since django offers a built-in web server during the development phase (and it’s written in python). Since I’m using a mac, I got some troubles to get mod_wsgi working. So far nothing too much annoying, but I wasted a bit of time so I hope these words can save someone else’s time :-)

I was not happy to use the Apache httpd which come built-in in OSX, so I downloaded the latest release from the Apache site (http://www.apache.org/dyn/closer.cgi ) and built it from scratch. Ensure you have the development tools installed in your OS, if not you can download them from the Mac App Store getting Xcode 4 for free…

So after a successful compile of sources

anubis:httpd-2.2.21 fabio$ ./configure \
&& make \
&& sudo make install

I found my apache 2 server ready under the directory /usr/local/apache2.

The next thing, is to install mod_wsgi . If you don’t want to use the built-in osx httpd, you have to download the sources (http://code.google.com/p/modwsgi/wiki/DownloadTheSoftware), and build them from scratch. This time, take care of where is the apache installation (did just some moments before) and where is your python!

Since I’m using virtualenv, I was almost sure to activate the environment settings and build mod_wsgi from the shell was sufficient… So far this is not the case, I needed to provide the installation path to the configure script, otherwise it will continue to use the python built-in with OSX:

anubis:mod_wsgi-3.3 fabio$ ./configure \
--with-apxs="/usr/local/apache2/bin/apxs" \
--with-python="/Users/fabio/Sviluppo/python-2.7/bin/python" \
&& make \
&& sudo make install

where /Users/fabio/Sviluppo/python-2.7/bin/python is the directory where I installed python 2.7 and django via virtualenv and pip.

It’s now time to configure Apache. Of course using vi :)

anubis:conf fabio$ sudo vi httpd.conf

and inside I added the following lines

Alias /media/ /Users/fabio/Sviluppo/booklibrary/media/

<directory /Users/fabio/Sviluppo/booklibrary/media>
Order deny,allow
Allow from all
</directory>

#MOD_WSGI
LoadModule wsgi_module modules/mod_wsgi.so

WSGIDaemonProcess books user=fabio group=staff python-path=/Users/fabio/Sviluppo/python-2.7/lib/python2.7/site-packages processes=2 threads=25

WSGIProcessGroup books

WSGIScriptAlias / /Users/fabio/Sviluppo/booklibrary/apache/booklibrary.wsgi
#WSGIScriptAlias /books /Users/fabio/Sviluppo/booklibrary/apache/test.wsgi

<directory /Users/fabio/Sviluppo/booklibrary/apache>
Order deny,allow
Allow from all
</directory>

Since the django app is in my home directory, we must ensure apache is able to run the code. This is accomplished with the lines

  • WSGIDaemonProcess books user=fabio group=staff …
  • WSGIProcessGroup books
The others are simply mappings and aliases which are almost straightforward.
Last but not least, the file .wsgi. I wrote 2 versions, one was a mere test of a correct installation of mod_wsgi in apache (test.wsgi):

import sys

def application(environ, start_response):
    status = '200 OK'
    output = 'It Works! -- Python executable at '+ sys.executable
    response_headers = [('Content-Type', 'text/plain'), ('Content-Length',   str(len(output)))]
    start_response(status, response_headers)
    return [output]

the other is the one which make the django app start:

import os
import sys

#sys.path.append('/usr/lib/python2.4/site-packages/django')
#/Users/fabio/Sviluppo/python-2.7/bin/
paths = ['/Users/fabio/Sviluppo',
        '/Users/fabio/Sviluppo/booklibrary']
for path in paths:
    if path not in sys.path:
        sys.path.append(path)

os.environ['DJANGO_SETTINGS_MODULE'] = 'booklibrary.settings'

import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()

And that’s all ;)