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?
.. contents::
Install Setup tools:
.. code-block :: bash
$ sudo apt-get install python-setuptools memcached
Install virtualenv:
.. code-block :: bash
$ sudo easy_install 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
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
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
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
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()
Reset apache2 so that it reads in the new config files:
.. code-block :: bash
$ a2ensite lostquery
$ sudo service apache2 reload
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
@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