MediaTemple CentOS 5.5 (VE) Server Build – Django 1.3, Python 2.7

THIS IS OUTDATED DOCUMENTATION. NEW VERSION AVAILABLE HERE:

http://blog.hackedexistence.com/mediatemple-centos-5-5-ve-server-build-django-1-3-python-2-7-mysql-5-5-php-5-3

VE Server

Media Temple is End-Of-Life-ing their Grid Server Django Containers.  As such, I had to migrate all my django sites off the grid onto a new (VE) server.  This is a guide for building a stock CentOS 5.5 server with django and python 2.7.

// SHOUT OUTS

Malcolm Frazier – Holding it down with all the linux knowledge.

// USER ACCOUNTS

The first step is to create a user account so you don’t have to use root

# useradd <username>
# passwd <username>

Add a user group so we can setup the sudoers file and add our new user account to the group

# /usr/sbin/groupadd <new_group_name>
# /usr/sbin/usermod -a -G <new_group_name> <new_user_name>

I like to use the locate command a lot, so lets build the index of file names to search from

# updatedb

Setup the sudoers config file

# vim /etc/sudoers

Add the following lines to the bottom of the file:

# Customizations
%<new_group_name>    ALL=(ALL)       ALL

At this point you should be able to exit ssh and log back in as your new user account.  You can use sudo <command> to execute commands as root, or use sudo -s as a replacement for su.

// UPGRADE PACKAGES SYSTEM WIDE

# yum upgrade

// INSTALLING PYTHON 2.7

I’ve chosen to use Python 2.7 as my version of python for django.  CentOS comes with Python 2.4 already installed.  I had some down time on a project because I asked the techs at RackSpace to upgrade the version of python on the server and they started by trying to uninstall Python 2.4.  The problem is that the yum package management system that CentOS uses is built on top of python.  If you uninstall python 2.4, you will not be able to use yum to install python 2.7, or any package at that point.  The solution is to install Python 2.7 in parallel to 2.4, have Django and all your other apps use the 2.7 install, and leave 2.4 to be used by yum.

Theres a great tutorial on installing Python 2.7 on CentOS 5 here.

Instead of using /usr/src/ for all the source code, I created /root/Source/ to hold the source from all the packages.  Inside of Source, download and extract Python 2.7:

# wget http://www.python.org/ftp/python/2.7/Python-2.7.tar.bz2
# tar -xvjf Python-2.7.tar.bz2
# cd Python-2.7
# ./configure --help

Read through the configure help and see if there are any options you want to enable or customize.  Then ./configure

# ./configure --prefix=/usr/local/python2.7

–prefix tells the configure script to install python into /usr/local/python2.7/ to create a completely separate parallel installation next to python 2.4.

Because of a mod_wsgi error that you will run into later, you should install the following dependencies before installing python:

# yum install readline-devel
# yum install gdbm-devel
# yum install sqlite-devel

After installing the dependencies, you can run ./configure again after you do a # make clean.  This will get rid of the old config file and generate a new one.

# make clean
# ./configure --prefix=/usr/local/python2.7

Assuming everything went well, build and install python 2.7

# make
# make install

// SETUP ENVIRONMENT VARIABLES

$ vim ~/.bashrc

Add the following to the bottom of .bashrc:

# User specific aliases and functions
alias python='/usr/local/python27/bin/python'

Log out, Log back in, and you should be able to execute the new Python 2.7

$ python
Python 2.7 (r27:82500, Mar 22 2011, 13:20:42)

// INSTALLING PIL (PYTHON IMAGING LIBRARY)

At this point, if you install PIL without first satisfying dependencies, PIL will be built without libjpeg and zlib (png support).  The output of python setup.py install would be:

*** TKINTER support not available
*** JPEG support not available
*** ZLIB (PNG/ZIP) support not available
*** FREETYPE2 support not available
*** LITTLECMS support not available

Unfortunately, PIL doesn’t complain very loudly and will still install a working version that will not be able to handle .jpg or .png files.  If you install PIL without the header libraries for the dependencies present, you will receive the following error in django’s admin when trying to upload a file:

Upload a valid image. The file you uploaded was either not an image or a corrupted image.

You can further verify if the proper support is compiled in from the shell:

$ python
>>> from PIL import Image
>>> i = Image.open("/path/to/some/image.jpg")
>>> i.verify()
>>> i.load()
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/usr/local/python2.7/lib/python2.7/site-packages/PIL/ImageFile.py", line 189, in load
d = Image._getdecoder(self.mode, d, a, self.decoderconfig)
File "/usr/local/python2.7/lib/python2.7/site-packages/PIL/Image.py", line 385, in _getdecoder
raise IOError("decoder %s not available" % decoder_name)
IOError: decoder jpeg not available

You can see from the above error that the jpeg decoder is not available.  If you’ve already installed PIL, uninstall it.  If you havn’t installed PIL yet, this will save you a lot of time (:

# yum install zlib zlib-devel
# yum install libjpeg libjpeg-devel
# yum install freetype freetype-devel

Django relies heavily on the Python Imaging Library PIL.  Again in our /root/Source/ directory, install PIL

# wget http://effbot.org/downloads/Imaging-1.1.7.tar.gz
# tar xvfz Imaging-1.1.7.tar.gz
# cd Imaging-1.1.7
# python setup.py build_ext -i

Check to make sure that libjpeg and zlib were found:

*** TKINTER support not available
--- JPEG support available
--- ZLIB (PNG/ZIP) support available
--- FREETYPE2 support available
*** LITTLECMS support not available

Run a test to make sure that everything works:

# python selftest.py
--------------------------------------------------------------------
PIL 1.1.7 TEST SUMMARY
--------------------------------------------------------------------
Python modules loaded from ./PIL
Binary modules loaded from ./PIL
--------------------------------------------------------------------
--- PIL CORE support ok
*** TKINTER support not installed
--- JPEG support ok
--- ZLIB (PNG/ZIP) support ok
--- FREETYPE2 support ok
*** LITTLECMS support not installed
--------------------------------------------------------------------
Running selftest:
--- 57 tests passed.

And finally, install PIL

# python setup.py install

You should now be able to import PIL inside of python:

$ python
>>>import PIL
>>>

// INSTALLING APACHE

Next we have to install our web server, Apache.  Theres a pretty straight forward tutorial on this here.

# yum install httpd
# /sbin/chkconfig httpd on
# /etc/init.d/httpd start
Starting httpd:                                            [  OK  ]

At this point, you should spend some quality time with /etc/httpd/conf/httpd.conf to really squeeze some power out of apache.

// INSTALLING MOD_WSGI

mod_wsgi is the link between apache and django.  It is responsible for taking the web request from apache, and getting it to your django app for handling.  The mod_wsgi installation docs are a great resource, they can be found here.

First, we need to install the source code for apache, as mod_wsgi needs it to build.  Install the httpd-devel package, which will install the headers for apache.

# yum install httpd-devel

Get and install mod_wsgi, again from /root/Source/

# wget http://modwsgi.googlecode.com/files/mod_wsgi-3.3.tar.gz
# tar -zxvf mod_wsgi-3.3.tar.gz
# cd mod_wsgi-3.3
# ./configure --help
# ./configure --with-python=/usr/local/python27/bin/python
# make
# make_install

// INSTALLING PHPMYADMIN

PhpMyAdmin is a web interface for controlling your MySQL database.  The RPM for PhpMyAdmin is in the rpmforge repo, so we will add that repo to yum.  Again from /root/Source/:

# wget http://packages.sw.be/rpmforge-release/rpmforge-release-0.5.2-2.el5.rf.i386.rpm
# rpm --import http://apt.sw.be/RPM-GPG-KEY.dag.txt
# rpm -K rpmforge-release-0.5.2-2.el5.rf.*.rpm
# rpm -i rpmforge-release-0.5.2-2.el5.rf.*.rpm
# yum search phpmyadmin
# yum install phpmyadmin

Setup the PHP Cookie

# vim /usr/share/phpmyadmin/config.inc.php

Add the Python Shared Libraries

# vim /etc/ld.so.conf.d/python2.7.conf

add the following line:

/usr/local/python2.7/lib

// INSTALLING DJANGO

The django install docs can be found here.

# wget http://www.djangoproject.com/download/1.3/tarball/
# tar xzvf Django-1.3.tar.gz
# cd Django-1.3
# python setup.py install
$ python
>>> import django
>>>

// POINT APACHE AT DJANGO USING MOD_WSGI
First, you need to tell apache which version of python to use so it doesn’t use the built in 2.4

# vim /etc/httpd/conf/httpd.conf

Add the following to the bottom of the file

#Python Versioning Control for mod_wsgi
WSGIPythonHome /usr/local/python2.7

Then restart apache

# /etc/init.d/httpd restart

Now you can configure your virtual hosts in apache to point to a ‘django.wsgi’ file thats specific to your django project. Add the WSGIScriptAlias to your Virtual Host

WSGIScriptAlias / /path/to/your/django/project/django_project_name/apache/django.wsgi

Add the ‘apache’ directory to your django project, and copy the following into django.wsgi inside of the apache folder

import os
import os.path
import sys

sys.path.append('/path/to/project/root')

os.environ['PYTHON_EGG_CACHE'] = '/path/to/a/directory/for/egg_cache'
os.environ['DJANGO_SETTINGS_MODULE'] = 'your_django_project_name.settings'

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

If you’ve made it this far, you should have a working django install.

This entry was posted in Django, Linux, Media Temple. Bookmark the permalink.

3 Responses to MediaTemple CentOS 5.5 (VE) Server Build – Django 1.3, Python 2.7

  1. (mt) Sara says:

    Great article! I’m happy to see that you’ve made a smooth transition to the powerful (ve) Server. I’ll pass that shout out along to Malcom for ya, too!
    Might you be interested in contributing to the (mt) Wiki? Give it a look!

    http://wiki.mediatemple.net/w/Contribute

  2. Möter says:

    The info about PIL’s dependencies… really helpful. Thanks!

Leave a Reply

Your email address will not be published. Required fields are marked *