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

VE Server

This is an updated version of an older blog post outlining a full (VE) build for django.  I had to update my server due to incompatibilities between the latest version of WordPress and the versions of PHP/MySQL found in the standard CentOS repos.

// SHOUTOUTS

Malcolm Frazier – (still) holding it down with 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 account to the group

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

I like to use the locate command a lot, so lets build the index of the file system that locate uses to search

# 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

*** The above modification more or less gives all users in <new_group_name> the ability to do anything root can do, without the root password.  This is fine for building the server, but after the server is built, you should restrict the permission levels a little bit more.

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 5.5 comes with Python 2.4 already installed.  I had some down time on a past project because I asked the techs at RackSpace to upgrade the version of Python on the server and they started by uninstalling 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 other 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 and the underlying OS.

Before we start compiling, lets install the GCC compiler:

# yum install gcc

This will prevent the following error from occurring if you try to compile python without gcc:

configure: error: in `/root/Source/Python-2.7':
configure: error: no acceptable C compiler found in $PATH

Additionally, you’ll want to install a few extra optional dependencies for Python

# yum install readline-devel gdbm-devel sqlite-devel
# yum install openssl-devel ncurses-devel bzip2-devel

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 run the configuration script:

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

–prefix tells python to install to a directory other than the default.  This is necessary if we want to run both 2.7 and 2.4 side by side.

–enable-shared will prevent an error later on when trying to build mod_wsgi.  If you get the following error when building mod_wsgi, recompile and reinstall python with –enable-shared:

/usr/local/python2.7/lib/libpython2.7.a: could not read symbols: Bad value
collect2: ld returned 1 exit status
apxs:Error: Command failed with rc=65536
make: *** [mod_wsgi.la] Error 1

Now its time to build and install Python:

# 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/python2.7/bin/python'

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

$ python
Python 2.7
>>>

// INSTALLING PIL (PYTHON IMAGING LIBRARY)

At this point, if you install PIL without first satisfying the optional 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 an image 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 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 MYSQL

Enable the Remi Repository to install MySQL 5.5 and PHP 5.3.  More information about the Remi Repository can be found here.

# wget http://download.fedora.redhat.com/pub/epel/5/x86_64/epel-release-5-4.noarch.rpm
# rpm -Uvh epel-release-5-4.noarch.rpm
# rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-5.rpm
# yum --enablerepo=remi list mysql mysql-server
# yum --enablerepo=remi install mysql.x86_64 mysql-server.x86_64

Start the MySQL Server:

# /etc/init.d/mysqld start

In order to set the initial root password, and get rid of the built in tables/user accounts for testing, run:

# /usr/bin/mysql_secure_installation

Follow the instructions, pick your customizations … then make sure MySQL is installed and working:

# mysql -u root -p
Enter password:
mysql> SELECT VERSION();
+-----------+
| VERSION() |
+-----------+
| 5.5.14    |
+-----------+
1 row in set (0.00 sec)

Add MySQL to the proper run level:

# /sbin/chkconfig mysqld on

// MYSQL-PYTHON GAP

Next, you need to install MySQL-python, the python interface to MySQL.  If you do not install MySQL-python, later on when you try to do a ‘python manage.py syncdb’ django will not be able to communicate with MySQL and will throw the following error:

django.core.exceptions.ImproperlyConfigured: Error loading MySQLdb module: No module named MySQLdb

Setuptools is a required dependency of MySQL-python.  Download it from here and install it, setting the prefix to our freshly installed python2.7

# sh setuptools*.egg --prefix=/usr/local/python2.7

Now install the MySQL headers from the Remi repo, then install MySQL-python:

# yum --enablerepo=remi install mysql-devel.x86_64
# wget http://sourceforge.net/projects/mysql-python/files/mysql-python/1.2.3/MySQL-python-1.2.3.tar.gz/download
# tar -zxvf MySQL-python-1.2.3.tar.gz
# cd MySQL-python-1.2.3
# python setup.py build
# python seutp.py install

At this point django should be able to talk to MySQL using MySQL-python.

// INSTALLING APACHE

Next we have to install our web server, Apache.  There’s 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 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
>>>

// INSTALLING PHPMYADMIN

PhpMyAdmin is a web interface for controlling your MySQL database.

# yum install phpmyadmin

This will install PHP as a dependency, but you will still need to setup PHP.  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

Create necessary links and cache the new libraries:

# ldconfig

// 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

# 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/python2.7/bin/python
# make
# make_install

// 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 default 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

Make sure you load mod_wsgi in httpd.conf at the end of the LoadModule section

LoadModule wsgi_module modules/mod_wsgi.so

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 each django project you create.  Add the WSGIScriptAlias to your Virtual Host configuration file:

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

Add the ‘apache’ directory to your django project, and create the django.wsgi file inside the apache directory:

$ cd /path/to/your/django/project/django_project_name/
$ mkdir apache
$ cd apache
$ vim django.wsgi

Copy the following into the django.wsgi file:

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 and tagged , , , , , , , . Bookmark the permalink.

One Response to MediaTemple CentOS 5.5 (VE) Server Build – Django 1.3, Python 2.7, MySQL 5.5, PHP 5.3

  1. (mt) Sara says:

    Nice! Thanks for sharing. Have you considered contributing to our KnowledgeBase or checking out our user forums? You should look into it! We’re always happy to have contributions & active members to help strengthen the community.

Leave a Reply