Saturday, April 14, 2012

Deploying Django, Apache, MySQL on Amazon EC2 Newbie Guide



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 (preferably using Mercurial and not Git :P ). 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 AWSaccount 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).

No comments:

Post a Comment