Non-techie Guide to setting up Django, Apache, MySQL on Amazon EC2

Sysadmin

Bruce Willis is THE SYSADMIN GUY

I don’t like sysadmin. I think someone needs to do a stable non beta version of Heroku for Django ASAP. Hence, I’m putting this little walkthrough to help anyone who might be trying to do what I think is a pretty common setup. Getting Django, Apache, MySQL to play together nicely on the free instance on Amazon EC2.

DISCLAIMER: I’m a sys admin NOOB. I am also teaching myself to code. This is my first time setting up this stack so there are probably going to be some bugs/security issues I conveniently side stepped just to get it to work. Tips from the pros on how to improve this process is greatly appreciated. But I did spend quite a bit of time researching and walking through the process on a new Amazon instance and it worked. So use this guide at your own risk.

The starting point of this guide assumes you have already signed up for an Amazon AWS account and that you have already created your free instance. We will be installing and setting up a test Django project together with Apache, mod_wsgi, phpMyAdmin and MySQL. This tutorial assumes you have basic working knowledge of commands in bash.

Step 1: Connect to your Instance

At some point of the creation of your instance, you should have created and downloaded your PEM key. Navigate to that folder in bash and type:

ssh -i <yourkeyname>.pem ec2-user@<YOUR PUBLIC DNS>

You can get this from right clicking on your instance in your AWS dashboard. I had to change root to ec2-user. Replace the public dns with your own.

Once you’re connected, you should be greeted with some ASCII art. Now change to root user by typing

sudo su

Step 2: Install Stuff

# Install Django (latest version is 1.3) from home directory
wget http://www.djangoproject.com/download/1.3/tarball/
tar xzvf Django-1.3.tar.gz
cd Django-1.3
sudo python setup.py install
# Run Python interpreter and import django.
# If you get the following error:

Python 2.6.6 (r266:84292, Jan 18 2011, 10:20:48)
[GCC 4.4.4 20100726 (Red Hat 4.4.4-13)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import django
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named django
>>>
>>>

# To fix this, run the following

ln -s /django-1.3/django /usr/lib/python2.6/site-packages/django
ln -s /django-1.3/django/bin/django-admin.py /usr/local/bin

# Install Apache
yum install httpd

# Install PHP libraries
yum install php libmcrypt libmcrypt-devel php-mcrypt php-mbstring

# Start Apache. The 2nd command starts the Apache service whenever
# your server reboots
service httpd start
sudo chkconfig httpd on 

# At this point, if you go to your public Amazon DNS in your browser, you should see the Apache test page.
# For my case, I entered http://ec2-122-248-213-159.ap-southeast-1.compute.amazonaws.com/ into my browser

# Install mod_wsgi
yum install mod_wsgi

# Install MySQL and related libraries
yum install mysql mysql-server MySQL-python

# Set password for MySQL root user
/usr/bin/mysqladmin -u root password '12345'

# create a dummy database
mysql -r root -p
# enter password. in this example we used 12345
create database test;

# Start MySQL
service mysqld start
sudo chkconfig mysqld on

Install phpMyAdmin by following the steps here (Warning: It’s quite long. You can skip this part if you want).

Step 3. Edit http.conf and create django.wsgi files and other stuff

First, create a new user and a new Django project

useradd djangotest
su - djangotest
django-admin.py startproject helloworld

Switch back to root user and open your httpd.conf file

sudo su
vim /etc/httpd/conf/httpd.conf

Towards the end of the document, uncomment

NameVirtualHost *:80

Then change <VirtualHost *:80> </VirtualHost> to this

<VirtualHost *:80>
    DocumentRoot /home/djangotest/helloworld
    ServerName <INSERT YOUR PUBLIC DNS HERE>
    ErrorLog /home/djangotest/helloworld/logs/apache_error.log
    CustomLog /home/djangotest/helloworld/logs/apache_access.log combined
    WSGIScriptAlias / /home/djangotest/helloworld/apache/django.wsgi

    Alias /phpmyadmin /var/www/html/phpmyadmin    
    <Location /phpmyadmin>        
        SetHandler None    
    </Location>
    <Directory /home/djangotest/helloworld/media>
        Order deny,allow
        Allow from all
    </Directory>

    <Directory /home/djangotest/helloworld/apache>
        Order deny,allow
        Allow from all
    </Directory>

    LogLevel warn

    Alias /media/ /home/djangotest/helloworld/media/
</VirtualHost>

I also had to change the user and group from apache to djangotest.

# use ?User within vi to search for this
User djangotest
Group djangotest

Now navigate into the folder where you ran django-admin.py startproject helloworld earlier and run this

mkdir apache
cd apache
vi django.wsgi

# paste this in 

import os,sys

apache_configuration = os.path.dirname(__file__)
project = os.path.dirname(apache_configuration)
workspace = os.path.dirname(project)
sys.path.append(workspace)
sys.path.append('/home/djangotest/helloworld')
sys.path.append('/home/djangotest')

os.environ['DJANGO_SETTINGS_MODULE'] = 'helloworld.settings'

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

Whilst you’re in the project directory, create the log folder and files

mkdir logs
cd logs
vim apache_error.log #save using :wq
vim apache_access.log #save using :wq

The paths here should match with the ErrorLogs in the httpd.conf you edited earlier.

ErrorLog /home/djangotest/helloworld/logs/apache_error.log

Step 4: The Easy Part

So all the hard parts are done, what’s left is to fill in the Django specific parts. I’ll just show the relevant parts of each code snippet

settings.py

DATABASES = {
    'default': {
        'ENGINE': 'mysql',
        'NAME': 'test',
        'USER': 'root',
        'PASSWORD': '12345',
        'HOST': '',
        'PORT': '',
    }
}

views.py

Create a new views.py document and add the following in

from django.http import HttpResponse

def home(request):
    return HttpResponse('Hello World')

urls.py

from django.conf.urls.defaults import patterns, include, url

urlpatterns = patterns('',
    url(r'^home/', 'helloworld.views.home', name='home'),
)

Fire up your browser and navigate to your <public dns>/home and you should see Hello World, <public dns>/phpmyadmin to get to phpMyAdmin if you installed it.

I ran into some issues trying to log into phpmyadmin. If you are having problems as well, leave a comment and I’ll try to help you out.

Note that after making changes to the httpd.conf file, it’s a good idea to restart Apache by typing this command:

service httpd restart

Also, in creating your security groups for your Amazon instance, you have to allow access to the ports 80 (for browsers) and 3306 (for MySQL) and any others that you need like Port 8000 and 22 (SSH).

P.S This is my first ever ‘technical’ tutorial. Feedback and comments welcome!
P.P.S This is obviously not secure enough for a ‘production’ environment. But it should be enough for you to host your own mini projects and share them with your friends/family for feedback!

Useful Links and Credits

  1. http://thomas.broxrost.com/2008/08/21/persistent-django-on-amazon-ec2-and-ebs-the-easy-way/
  2. http://www.calebogden.com/wordpress-on-linux-in-the-amazon-cloud-with-mac/
  3. http://aws.amazon.com/documentation/ec2/
  4. http://stackoverflow.com/questions/5264811/how-do-i-run-django-and-phpmyadmin-on-apache-webserver-on-ubuntu
  5. http://oligoli.wordpress.com/2009/03/21/problem-with-installing-mysqldb-in-python/
  6. http://docs.djangoproject.com/en/dev/howto/deployment/modwsgi/
  7. http://code.google.com/p/modwsgi/
About these ads

22 thoughts on “Non-techie Guide to setting up Django, Apache, MySQL on Amazon EC2

  1. Agree that trunk is probably not advised. But you can just svn update to the version of choice.

    Wasn’t clear what OS you are using. Ubuntu would seem easier.

    Heck out dot cloud. Kind of like heroku for everything.

    Also, web2py is quite a it easier than django.

  2. Thanks, Nai. I was just going through the same exact setup, and you helped me with a few steps! One correction. I am no expert either, but believe that
    sudo chkconfig httpd start
    should instead be
    sudo chkconfig httpd on
    Same for the MySQL service.

  3. Pingback: My First Databound Python/Django Powered Webapp | pragmaticstartup

  4. Nice clear and straightforward example thanks! The mod_wsgi setup though is single-threaded, have you tried a multithreaded setup? ie: WSGIDaemonProcess server user=apache group=apache processes=# threads=#

    Doing so I got an error related (i think) to installing mod_wsgi < version 3.3, the version installed from the repo by default is 3.2-1.5.amzn1. Compiling mod_wsgi 3.3 from the source has caused subsequent headaches…

  5. hey,
    could you please give some information about how to access the admin page? I keep getting DoesNotExist at /admin/
    Site matching query does not exist.
    error.

    thanks!

  6. Thanks for the quick setup instructions! This is my first EC2 instance and needed something like this to get me started. In the “install stuff” section between install mysql and set password, you should add “start mysql with ‘/etc/init.d/mysqld start’

    Thanks again!

  7. Pingback: Cgi script installation service

  8. Pingback: Setting up Django on amazon ec2 server | BenjaminPurdy

  9. Pingback: Installing and Setting up my First Django Project [Unfinished] | 白いキウィの大冒険

  10. Pingback: Deploying Python, Django on ec2 linux instance by GuoChen

  11. Pingback: Data Community DC: A Tutorial for Deploying a Django Application that Uses Numpy and Scipy to Google Compute Engine Using Apache2 and modwsgi | The Black Velvet Room

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s