Getting Apache ready for serving Python applications seems to really be a headache. mod_python
seems relatively easy, but the preferred mod_wsgi
seems to give everyone headaches. I wanted to serve my python applications using MAMP since it's part of my daily workflow. I found a decent solution that is working really well for me with MAMP on OSX (Leopard). You may want to check out my previous post on installing and managing a basic OSX Django Stack before reading this one.
To install WSGI, you need to compile it against the version of Apache you'll be using it with. MAMP's current packaged version of Apache is 2.0.63, which is not super new, but will do. If you're like me and you just installed the MAMP binary instead of downloading the source code...well, then you don't have the Apache source code for 2.0.63, do you? So, let's get it!
I had already installed Macports in my previous adventure with Django installs. I decided to see what was available Apache-wise, and lo-and-behold:
$ port search "apache" apache20 @2.0.63 (www) The extremely popular second version of the Apache http server
The exact same version that MAMP is packaged with! Awesome! Let's install it...
$ port install apache20
That'll install Apache in /opt/local/apache20 (or wherever Macports is installing stuff on your machine). Next you'll need to grab the mod_wsgi source from author Graham Dumpleton (thanks, Graham!). Unpack that tar.gz file and fire up terminal and cd into that folder. First read this code section:
mod_wsgi-3.2 $ ./configure checking for apxs2... no checking for apxs... /usr/sbin/apxs checking Apache version... 2.2.14 checking for python... /Library/Frameworks/Python.framework/Versions/2.6/bin/python configure: creating ./config.status config.status: creating Makefile
So our basic configure checks for apxs (apache extension tool) and finds the default OSX install – which for me is currently 2.2.14; too new for MAMP. So go ahead and add the --with-apxs flag to the configure and point to wherever Macports installed your apache20:
mod_wsgi-3.2 $ ./configure --with-apxs=/opt/local/apache20/bin/apxs checking Apache version... 2.0.63 checking for python... /Library/Frameworks/Python.framework/Versions/2.6/bin/python configure: creating ./config.status config.status: creating Makefile
Ok, so the Apache version looks right this time. Let's make and install that guy:
$ make $ sudo make install chmod 755 /opt/local/apache20/modules/mod_wsgi.so
Cool, so looks like it copied the compiled wsgi module into our apache20 installation. Now we just need to copy it to /Applications/MAMP/Library/modules (your MAMP modules folder).
Fire up MAMP Pro and go to File > Edit Template > Apache httpd.conf. Add the following after the other LoadModule directives:
LoadModule wsgi_module modules/mod_wsgi.so
Ok, that's the install. Stop and start MAMP services and you've got WSGI ready to serve python apps. Next step is to configure a Django site to be served.
To start, I've commited my "learning" code to github, so you can check out how I'm learning how to set up and use Django on my machine. I'll be referencing these files throughout so grab them if you want them. I'm also assuming you've created a basic Django project and an application. My learning code uses the same code from the introduction tutorial on the djangoproject.com site. My sample code is in a directory called "project" and I have an application called "polls."
First thing you want to do is create a named host like you always do with MAMP. Switch to the hosts panel and hit the "+" button. I called this one "django.dev". In the General settings, point the document root to your project's root; in my case it points to /Library/WebServer/Documents/Django/project.
Now in your django project, create a folder called "apache" and create two files there.
/project/ /apache/ apache_django_wsgi.conf django.wsgi settings.py polls ...
See the two files and folder stucture on github here. django.wsgi is your primary wsgi application. This is mounted as the root of your website:
import os, sys # path to parent folder of project sys.path.append('/Library/Webserver/Documents/Django') # path to your settings module os.environ['DJANGO_SETTINGS_MODULE'] = 'project.settings' # create a wsgi "application" import django.core.handlers.wsgi application = django.core.handlers.wsgi.WSGIHandler()
You can see my setup here. apache_django_wsgi.conf is the httpd.conf file for your VirtualHost:
Alias /static /Library/Webserver/Documents/Django/project/static <Directory /Library/Webserver/Documents/Django/project/media> Order deny,allow Allow from all </Directory> WSGIScriptAlias / /Library/Webserver/Documents/Django/project/apache/django.wsgi
You can see that mine defines an alias that points to a static folder (where I'll serve my js, css, images from for now) and a WSGIScriptAlias
which is the full path to my .wsgi application.
Now back in MAMP, go to the advanced settings of your virtual host and in the "Customized virtual host general settings" add:
Include /Library/Webserver/Documents/Django/project/apache/apache_django_wsgi.conf
This would be the full path to your .conf file in your project. Again, restart MAMP's services. So now when you hit django.dev, the application defined in your .wsgi will be served. django.dev/static/ will be avaiable for you to add static content like js, css, etc. The end.