« Crystal Works Rebranding | Miracles Happen »
Deploying a Django website on Ubuntu@SliceHost
Posted in Django, Web Development by Florin on Apr. 30th 2008 @ noon
For hosting www.crystal-works.net I’ve signed up for a SliceHost 256MB VPS slice. The price is unbeatable among the VPS hosting providers ($20/month) and even better than this, SH slices support the recently released Ubuntu Hardy (Yay!) :D.
I’ve chosen to have my Django app served by Apache2 and mod_python (static resources included) and rely on PostgreSQL 8 for the DB side.
So here’s a quick and dirty guide for setting up your Django powered website on a clean Hardy distro.
Getting started: Install the required Ubuntu packages
If you have just acquired your slice it’s recommended that you create a regular user account to which you assign superuser privileges via the sudo command, instead of using the default “root”. Accomplishing this requires minimal sys-admin knowledge and it is outside the scope of this article, but I thought about making this recommendation and justify for the sudos you’ll encounter below.
# install mod_python (in my case this installed also the Apache2 server
# and several other dependencies)
host:~$ sudo aptitude install libapache2-mod-python
# per some Django docs recommendations we'll have to use the Apache2 prefork MPM
# instead of the default worker MPM, so here it goes ...
host:~$ sudo aptitude install apache2-mpm-prefork
# install the PostgreSQL server and client
# in Hardy's case these virtual packages default to PostgreSQL 8.3
host:~$ sudo aptitude install postgresql postgresql-client
# install other deployment/setup related goodies
host:~$ sudo aptitude install rsync subversion
# install the python PostgreSQL support libraries and other Django friendly packages
host:~$ sudo aptitude install python-imaging python-docutils python-psycopg2
Download and setup Django
With all these in place, it’s time to set up Django. I’ll use the development version, fetched from the official repository using Subversion. I’ll also create a dedicated home directory for holding the Django distro. This will allow me tagging separate revisions, and relatively easy switch between them, in case of backward compatibility breaks. For the moment, though, just the trunk should do.
# create the home directory
host:~$ sudo mkdir /home/django
host:~$ cd /home/django/
host:/home/django$ sudo svn co http://code.djangoproject.com/svn/django/trunk/ trunk
# make Django available to Python
# I've chosen to create a symlink to the site-packages directory
host:/home/django$ sudo ln -s /home/django/trunk/django/ /usr/lib/python2.5/site-packages/
# make the django-admin.py script easily available
# for this, I'll symlink the site-packages/django/bin/ located script to /usr/local/bin
host:/home/django$ sudo ln -s /usr/lib/python2.5/site-packages/django/bin/django-admin.py /usr/local/bin/
Now it’s time for a simple test to make sure the django-admin.py tool is accessible from the system path and that the actual Django framework works:
# return to user home
host:/home/django$ cd
host:~$ django-admin.py --version
0.97-pre-SVN-7510
# hooray!
If you see something similar—except maybe for the revision number (7510)—then you’re done with the Django setup and installation.
Transfer your Django project to the production server
Now it’s time to upload the Django project to your slice. For this, I’ll be creating a ”/home/sites/” directory on server and reference to this location from now on, but you may put it wherever you please, as long as you stick to that location in the upcoming steps. This directory will hold each individual web site hosted in their own subdirectory. So the actual Django website will reside in ”/home/sites/mysite/”.
# create the main /home/sites directory and the subdirectory for your 1st hosted web site
# in 1 step, this would be accomplished by
host:~$ sudo mkdir -p /home/sites/mysite
# change the owner of your project subdirectory to your regular Ubuntu user (from the current "root")
# for allowing rsync transfers from your development box using your regular SSH connection settings
host:~$ sudo chown jdoe.jdoe /home/sites/mysite/
# the above line assumes "jdoe" is your regular account
For uploading the project tree from my dev. box to the server, I’ll use rsync (easily available on Mac OS X and most Unix flavors). The below commands run from your development machine assume the project will be installed on your server under /home/sites/mysite/ and transfered via SSH using jdoe@example.com as credentials for your connection to the server.
devbox:mysite$ rsync --progress -azC --force --delete --exclude="*.pyc" -e "ssh" ./ jdoe@example.com:/home/sites/mysite
For more details about the rsync flags used, man rsync might shed some light. It’s also a good idea that you create a simple shell script for running this, as you’ll be using it every time you want to transfer your updates to the production box. Additional customization of the rsync command might be needed in a real life scenario, but this alone could be the subject of a tutorial, so for the moment the above sample should do.
At this point, you should be able to log in to your slice and check that everything worked, by running ./manage.py shell within your /home/sites/mysite directory. If there are any exceptions thrown when you run this, probably they are caused by missing python packages needed by your project, so you should start investigating from there. This is how it should look like if everything is OK:
host:/home/sites/mysite$ ./manage.py shell
Python 2.5
[GCC 4.x.x (Ubuntu)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>>
Minimal PostgreSQL setup sample
At this point you should setup and populate the database for your web site. Below is just a sample of how you can quickly accomplish this. For additional information, you should consult the PostgreSQL manual
# create the DB user for your web site
# you will be prompted by some questions -- you should be a bit familiar with PostgreSQL
host:~$ sudo su postgres -c "createuser mysite_user"
# create the actual database (owned by the previously created user)
host:~$ sudo su postgres -c "createdb mysite_db -O mysite_user"
# at this point you should set the authentication mechanism for your new database and user
# in the "/etc/postgresql/8.3/main/pg_hba.conf" file, restart the server and make sure
# you can connect with the Postgre client
host:~$ psql -U mysite_user mysite_db
After making sure everything regarding the DB credentials works, you should populate it by either importing a previously created dump, or by falling back to the ./manage.py syncdb task provided by your Django project. I won’t further detail this, as you should probably already be familiar with this step since first developing your app.
Apache virtual host configuration
Providing you were able to successfully complete the previous steps, this should be the last task towards having a running web site.
First make sure, mod_python is enabled in your running web server. If you followed the previous steps (including the initial packages install) it should already be in place, otherwise you can make sure that it is enabled by checking for the existence of the mod_python.load symlink, within the /etc/apache2/mods-enabled directory. If you can’t find it there, but the package is installed, probably all you have to do is run sudo a2enmod mod_python and restart Apache.
Next, if you followed the steps above and you have a clean install of Apache, you should disable the default site provided in the Apache distro. For this you should run sudo a2dissite default.
Now it’s time to create an Apache virtual host for serving your web site. For this, all you have to do is create a file named after your web site’s name or domain (mysite or example.com, for eg) in the /etc/apache2/sites-available directory, and fill it with something like this:
<VirtualHost *>
ServerAdmin webmaster@example.com
ServerName example.com
Alias /static /home/sites/mysite/media
ErrorLog /var/log/apache2/error.log
LogLevel warn
CustomLog /var/log/apache2/access.log combined
ServerSignature Off
<Location "/">
SetHandler python-program
PythonHandler django.core.handlers.modpython
SetEnv DJANGO_SETTINGS_MODULE mysite.settings
PythonDebug Off
PythonPath "['/home/sites','/home/sites/mysite'] + sys.path"
</Location>
<Location "/static">
SetHandler None
</Location>
</VirtualHost>
The above configuration file might vary a little in your case because it assumes you are serving the media files from the media/ directory in your Django project, while the actual URL/location for GETing them is /static/, but you may further tune it to fit your needs.
After you set the proper location & paths for your media files, all there’s left to do it enable the newly defined site (virtual host) by running sudo a2ensite mysite (in case you named your config file mysite, otherwise replace mysite by example.com if you followed the above recommandation) and restart the Apache server—/etc/init.d/apache2 restart
Now cross fingers and try to browse your new web site :D
Closing statement
This is by far a complete guide because it assumes at least minimal knowledge of Apache, Python & PostgreSQL and it requires some security measures involving these components that I couldn’t detail in this post (otherwise it would have turned into something too comprehensive to be easily followed along the lines), but if you want to go more into detail regarding any of the steps above I recommend that you check out some of the following resources—on which most of this post is based:
- The Django installation guide
- Using Django with mod_python
- The SliceHost articles on Ubuntu Hardy
- The PostgreSQL 8.3 interactive manual
Disclaimer: I don’t pretend to be very experienced in deploying Django applications, plus, as mentioned above, this post is not meant to be a comprehensive guide, still if you spot any issues or major missing pieces, please comment.
Post a comment | 1 comment(s) | Related tags: django, python, slicehost, websites




Geoff said on May. 19th 2008 @ 12:52 p.m. EEST