HOWTO: Set up a Persistent Django Environment in Ubuntu on Amazon’s Elastic Compute Cloud (EC2)

The other day, I came across a great writeup by
Thomas Brox Røst on how to set up persistent storage for a Django environment with Amazon’s EC2. It’s an excellent and informative article, but I preferred to set up my environment with a number of differences, such as Ubuntu and MySQL instead of Fedora and PostgreSQL, as well as an apache2/mod_wsgi environment. The instructions are very similar, and I mostly recorded them for the sake of personal repetition, but I figured I’d share them in case anyone else finds them useful.

# original credit to Thomas Brox Rost
# http://thomas.broxrost.com/2008/08/21/persistent-django-on-amazon-ec2-and-ebs-the-easy-way/
# Howto by Ben Sarsgard
# This document lives at http://atzok.com/howto_django_ec2

# find an appropriate ami
# I very much like the offerings at http://alestic.com/
# add it to a security group
# open port 80 on that group

# set up server
apt-get update
apt-get install vim
apt-get install subversion
apt-get install apache2 libapache2-mod-wsgi
apt-get install python-setuptools
apt-get install python-mysqldb
# the following are optional, but will be needed if you want to package
# an AMI to reuse this image.
apt-get install ec2-ami-tools ec2-api-tools
# you may need to set JAVA_HOME

# mysql
apt-get install mysql-server

mysql -u root -p -e “CREATE DATABASE django;”

# install django
cd /opt
svn co http://code.djangoproject.com/svn/django/trunk/ django-trunk
ln -s /opt/django-trunk/django /usr/lib/python2.6/dist-packages/django
ln -s /opt/django-trunk/django/bin/django-admin.py /usr/local/bin
# I use /srv instead of /home because home directories are for users,
# whereas django code is theoretically shared and code being served
# belongs in /srv (or /opt, but that’s more for content that’s not being
# specifically served up, like the django source earlier)
mkdir /srv/django
cd /srv/django
django-admin.py startproject mysite

# set up wsgi
# edit /etc/apache2/sites-enabled/000-default
Alias /robots.txt /srv/django/mysite/static/robots.txt
Alias /favicon.ico /srv/django/mysite/static/favicon.ico
Alias /media/ /srv/django/mysite/static/media/
Alias /admin/media /srv/django/mysite/static/admin-media
Alias /styles/ /srv/django/mysite/static/styles/

Order deny,allow
Allow from all

WSGIScriptAlias / /srv/django/mysite/apache/django.wsgi

Order deny,allow
Allow from all

# end edit
mkdir /srv/django/mysite/apache
mkdir -p /srv/django/mysite/static/media
mkdir /srv/django/mysite/static/styles
ln -s /usr/lib/python2.6/dist-packages/django/contrib/admin/media /srv/django/mysite/static/admin-media
# edit /srv/django/mysite/apache/django.wsgi
import os
import sys
os.environ[‘DJANGO_SETTINGS_MODULE’] = ‘mysite.settings’

import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
# end edit

# test it out
apache2ctl restart
curl http://localhost/
# should output html including ”

It worked!

# set up the db
# edit /srv/django/mysite/settings.py
DATABASE_NAME = ‘mysite_django’
# end edit
# edit /srv/django/mysite/urls.py and uncomment out the admin stuff
# edit /srv/django/mysite/settings.py and add “django.contrib.admin” to your INSTALLED_APPS setting
# and set ADMIN_MEDIA_PREFIX = ‘/admin/media/’
cd /srv/django/mysite
python manage.py syncdb
# check out http:///admin/
# log in!

# create volume
# attach volume /dev/sdh
mkfs.ext3 /dev/sdh
echo “/dev/sdh /vol ext3 noatime 0 0” >> /etc/fstab
mkdir /vol
mount /vol
df –si
# should show up!

# move the database
service mysql stop
mkdir -p /vol/mysql
mv /var/lib/mysql/mysite_django /vol/mysql
ln -s /vol/mysql/mysite_django /var/lib/mysql/mysite_django
service mysql start