Tag apache

Django 1.5 on Webfaction

The setup of a Django application on Webfaction is really easy using their one-click-installer. But this setup is really static and surely not the best option to use for Django. Luke Plant wrote about setting up Django with gunicorn on Webfaction in his blog, I will write about setting up Django 1.5 with Apache and mod_wsgi without the Django one-click-installer but the mod_wsgi one (mod_wsgi 3.4 / Python 2.7). The setup won't be the fastest Django setup in the world, but it will work.
It's basically an update for my old blog post covering Django 1.3:

Set up a mod_wsgi application and create a website in the Webfaction control panel. Log into shell and goto your newly created app. Create a virtualenv and a folder for your project files (maybe you want to check out from a VCS), activate the virtualenv and install Django an whatever you need. Edit the default wsgi.py create by the django-admin.py startproject command:

"""
WSGI config for tools_project project.

This module contains the WSGI application used by Django's development server
and any production WSGI deployments. It should expose a module-level variable
named ``application``. Django's ``runserver`` and ``runfcgi`` commands discover
this application via the ``WSGI_APPLICATION`` setting.

Usually you will have the standard Django WSGI application here, but it also
might make sense to replace the whole Django WSGI application with a custom one
that later delegates to the Django one. For example, you could introduce WSGI
middleware here, or combine a Django application with an application of another
framework.

"""
import os

# set paths correctly on webfaction
if os.environ['STAGE'] == 'webfaction':
    import site
    import sys

    site.addsitedir('/home/<username>/webapps/<app>/<virtualenv-folder>/lib/python2.7/site-packages')
    sys.path.append('/home/<username>/webapps/<app>/project')

# We defer to a DJANGO_SETTINGS_MODULE already in the environment. This breaks
# if running multiple sites in the same mod_wsgi process. To fix this, use
# mod_wsgi daemon mode with each site in its own daemon process, or use
# os.environ["DJANGO_SETTINGS_MODULE"] = "tools_project.settings"
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "tools_project.settings")

# This application object is used by any WSGI server configured to use this
# file. This includes Django's development server, if the WSGI_APPLICATION
# setting points here.
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()

# Apply WSGI middleware here.
# from helloworld.wsgi import HelloWorldApplication
# application = HelloWorldApplication(application)

You can leave out the check of the STAGE environment variable if you haven't set it. I use it to run a project on different hosts and identify each host.

Now adjust the Apache2 config by editing /home/<username>/webapps/<app>/apache2/conf/httpd.conf. Remove the following lines on the bottom:

<Directory /home/<username>/webapps/<app>/htdocs>
    AddHandler wsgi-script.py
</Directory>

Instead, add the following line that tell the WSGI daemon to run the wsgi.py of Django:

WSGIScriptAlias / /home/<username>/webapps/<app>/project/<projectname>/wsgi.py

Then restart the Apache and you're done.

Django with virtualenv on Webfaction

I really like the Django web framework and I like virtualenv enabling me to use different python configs and packages for different projects. And I have to say I like Webfaction, so easy, so good! (No, I don't get paid by them) This is a quick guide on how to setup Django in virtualenv using mod_wsgi with a Webfaction account.

  • Create an "mod_wsgi" application and create a website to use this application
  • connect to your accounts shell using ssh
  • enable Python 2.6.x as default Python interpreter (as written in the Webfaction documentation)

echo "alias python=python2.6" >> ~/.bash_profile
source ~/.bash_profile
python -V
  • install "pip" and "virtualenv" (be sure to use easy_install-2.6 to use the setuptools of Python 2.6.x):

easy_install-2.6 -U pip
easy_install-2.6 -U virtualenv
  • I like yolk, that enables you to list the installed Python packages, install it using pip if you like

pip install yolk
  • Note that these packages (pip, virtualenv, yolk) are installed in your global Python. I recommend to not install any more packages to the global installation as virtualenv enables use to install all packages we need into the virtualenv Python lib.
  • navigate to your recently create mod_wsgi webapp, there should be 2 folders, "apache2" and "htdocs"
  • create the virtualenv for your project in the webapp folder, name it like you want, I'll use "ve" here

virtualenv --no-site-packages --distribute ve
  • a new folder "ve" with the virtualenv was created. Please refer to the virtualenv documentation for more information and usage of virtualenv.
  • Now let's install yolk into the virtualenv to see which packages are in there
    • either activate the virtualenv and install or use pip magic to install into an virtualenv without activating it:

source ve/bin/activate
pip install yolk
// or
pip -E ve install yolk
  • now you activate the virtualenv and execute yolk:

source ve/bin/activate
yolk -l
deactivate
  • Install Django and any requirements the same way as demonstrated for yolk.
  • Assuming you installed Django into the virtualenv and created a Django project, we now must adjust the Apache config
    • backup the httpd.conf from /webapps/<yourdjangoapp>/apache2/conf
    • create a django.wsgi file somewhere in your webapp directory (I use the conf folder of apache)
    • scan the httpd.conf for "Listen XXX", XXX ist the webapp port
    • remove the <Directory>...</Directory> segment
    • append the following telling the Apache to use the wsgi config we create in the next step:

NameVirtualHost *:<webapp-port>
<VirtualHost *:<webapp-port>> ServerName <SomeServerName> WSGIScriptAlias / /home/<your-username>/webapps/<your-webapp-name>/apache2/conf/django.wsgi </VirtualHost>
  • Edit the django.wsgi file:

#!/usr/bin/python
import os, sys, site
# add virtualenv python libs
site.addsitedir('/home/<your-username>/webapps/<your-webapp-name>/ve/lib/python2.6/site-packages')
# append the project path to system path
sys.path.append('/home/<your-username>/webapps/<your-webapp-name>/ve/')
sys.path.append('/home/<your-username>/webapps/<your-webapp-name>/ve/<your-django-project-name>')
# set the settings module
os.environ['DJANGO_SETTINGS_MODULE'] = '<your-django-project-name>.settings'
# init the wsgi handler
from django.core.handlers.wsgi import WSGIHandler
application = WSGIHandler()
  • Restart the Apache (/home/<your-username>/webapps/<your-webapp-name>/apache2/bin/restart) and everything should be fine!