=================================
django-virtualenv-apache-mod_wsgi
=================================


django-virtualenv-apache-mod_wsgi
=================================

Django virtualenv Apache2 mod_wsgi
==================================

By the end of this article you will know how to deploy a Django web
application using a python virtualenv, using an Apache2 webserver with
mod_wsgi.

You should bookmark this page.

**Why use wsgi and virtualenv?**

-  I also host pylons applications using mod_wsgi and apache2 and
   mod_python is incompatible.
-  mod_wsgi is fast.
-  I don’t want my public site-packages library conflicting with other
   applications.

.. contents::

Install virtualenv
------------------

#. Install Setup tools:

   .. code-block :: bash

   $ sudo apt-get install python-setuptools memcached

#. Install virtualenv:

   .. code-block :: bash

   $ sudo easy_install virtualenv

Create a virtualenv
-------------------

#. Move to the directory where you want to create the virtualenv:

   .. code-block :: bash

   $ cd /www/lostquery.com

#. Create python environment:

   .. code-block :: bash

   $ virtualenv –no-site-packages virtpy

Install Django
--------------

#. Activate the virtualenv:

   .. code-block :: bash

   $ source virtpy/bin/activate

#. The shell should have changed to *(virtpy) $* . Run this command to
   install django to the virtualenv:

   .. code-block :: bash

   # I know this version works… $ easy_install django==1.3.1

#. Install any dependencies you will need to the virtualenv:

   .. code-block :: bash

   $ easy_install MySQL-python markdown html5lib modwsgideploy
   python-openid South python-memcached

Install and configure the Django web application
------------------------------------------------

#. Get the sourcecode:

   .. code-block :: bash

   $ svn co http://svn.osqa.net/svnroot/osqa/trunk

#. Configure the application:

   .. code-block :: bash

   $ cd trunk

   $ cp settings_local.py.dist settings_local.py

   $ vi settings_local.py

#. You must tell the Django’s application what database to use. Also
   configure memcached:

   .. code-block :: python

   # database settings DATABASE_NAME = ‘databasename’ # Or path to
   database file if using sqlite3. DATABASE_USER = ‘username’ # Not used
   with sqlite3. DATABASE_PASSWORD = ‘p@ssw0rd’ # Not used with sqlite3.
   DATABASE_ENGINE = ‘mysql’ #mysql, etc DATABASE_HOST = ‘localhost’
   DATABASE_PORT = ’’

   # memcached settings (osqa is slow as dirt without this)
   CACHE_BACKEND = ‘memcached://127.0.0.1:11211/’

#. Give apache access to a few directories, /trunk/log and
   /trunk/forum/upfiles:

   .. code-block :: bash

   $ chmod 777 log $ chmod 777 forum/upfiles

#. Create the database
   ``(example syntax to create a mySQL database) <http://www.foxhop.net/mySQL#create-database>``\ \_.

   Let the django application build the tables in the new database:

   .. code-block :: bash

   $ python manage.py syncdb –all $ python manage.py migrate forum –fake

Configure Apache2 VirtualHost
-----------------------------

#. Turn on mod_rewrite:

   .. code-block :: bash

   $ a2enmod rewrite

#. Create a sites-available vhost apache2 file:

   .. code-block :: bash

   $ sudo vi /etc/apache2/sites-available/007-lostquery

#. Setup the host file:

   .. code-block :: apache :linenos:

   #lostquery.com

   #Djangos embeded mod_wsgi <VirtualHost \*:80> ServerName
   lostquery.com ServerAlias www.lostquery.com ServerAdmin
   admin@admin.com

   ::

         # ReWrite URL to WWW
         RewriteEngine On
         RewriteCond %{HTTP_HOST} ^www.lostquery.com
         RewriteRule (.*) http://lostquery.com$1 [R=301,L]

         # Log Files
         ErrorLog /var/log/apache2/error-lostquery.log
         CustomLog /var/log/apache2/access-lostquery.log combined

         # Prevent django from serving static files
         DocumentRoot /www/lostquery.com/trunk/forum
         Alias /m/ /www/lostquery.com/trunk/forum/skins/
         Alias /upfiles/ /www/lostquery.com/trunk/forum/upfiles/
         <Directory /www/lostquery.com/trunk/forum/skins>
             Order allow,deny
             Allow from all
         </Directory>

         # Setup mod_wsgi
         WSGIDaemonProcess lostquery display-name=lostquery user=www-data processes=2 threads=15
         WSGIScriptAlias / /www/lostquery.com/mod_wsgi/dispatch.wsgi

Configure mod_wsgi
------------------

#. Create the egg-cache directory:

   .. code-block :: bash

   $ mkdir /www/lostquery.com/mod_wsgi

   $ mkdir /www/lostquery.com/mod_wsgi/egg-cache

#. Create the wsgi dispatch file:

   .. code-block :: bash

   $ vi /www/lostquery.com/mod_wsgi/dispatch.wsgi

#. Setup the wsgi dispatch file:

   .. code-block :: python :linenos:

   import os import sys sys.stdout = sys.stderr # Add the virtual Python
   environment site-packages directory to the path import site
   site.addsitedir(‘/www/lostquery.com/virtpy/lib/python2.6/site-packages’)

   | # Avoid ``[Errno 13] Permission denied: '/var/www/.python-eggs'``
     messages
   | import os os.environ[‘PYTHON_EGG_CACHE’] =
     ‘/www/lostquery.com/mod_wsgi/egg-cache’

   #If your project is not on your PYTHONPATH by default you can add the
   following sys.path.append(‘/www/lostquery.com/trunk’)
   os.environ[‘DJANGO_SETTINGS_MODULE’] = ‘settings’

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

Enable the Virtual Host and reload Apache2
------------------------------------------

#. Reset apache2 so that it reads in the new config files:

   .. code-block :: bash

   $ a2ensite lostquery

   $ sudo service apache2 reload

fritzvd — Sep 28, 2011 11:31 pm
-------------------------------

Hi,

Thanks this is great and exhaustive. Helped me host my django. One
question though, I usually do this: Create sites and put them in:
sites-available. Reload apache2 for a graceful restart. Call them/switch
on:

::

   a2ensite lostquery

   /etc/init.d/apache2 reload

Is there any special reason why you don’t do this?

Fritz

foxhop — Sep 29, 2011 05:00 pm
------------------------------

@fritzvd

I have recently started using the *a2ensite* method that you described.

Thanks for your input. I have adjusted the tutorial. Feel free to adjust
anything you feel need work!

Foxhop
