I do on Django the
Encyclopedia of programming languages about which I already wrote on
Habré . During the work of the site it turned out that we need our own dedicated server for greater performance and stability. So far, I have taken a cheap server with a 1.8 GHz processor and 512 MB of memory.
In this article I will discuss installing and configuring Django on this server with mod_python for Apache, with memcached and lighttpd caching for static files.
So, we have a freshly installed CentOS 5 and a desire to host a site on Django (or several sites).
')
What do you need to install for this?
- Django proper
- MySQL-python
- mod_python
- memcached
- lighttpd
All steps, apart from installing Django itself, are optional (for example, you can use Django with fcgi instead of mod_python and PostgreSQL or another DBMS instead of MySQL), but steps 1-3 are what you are likely to use and 4-5 for increase productivity.
The article is mainly CentOS-oriented, but to a certain extent suitable for other Linux distributions.
Security note: since this is a freshly installed system, I’m not afraid to break something already working, so I can work as root. But it is better, of course, to work under the rights of an unprivileged user, and use “sudo” for commands that require administrative privileges.
Let's start.
Django properIn most cases, it is worthwhile to install the latest svn version of Django, not “release”. At the moment, the “official release” is too outdated and lacks many useful features (for example, unicode support and auto-escape).
To install, enter on the command line
svn co http://code.djangoproject.com/svn/django/trunk/ django-trunk
But first you need to install svn
yum install subversion
After receiving all the files from svn, you need to make a symbolic link to Django in the site-packages directory for Python:
ln -s `pwd` / django-trunk / django /usr/lib/python2.4/site-packages/django
Make sure that all the parent directories in the django directory have the correct permissions (read access for the httpd user, usually chmod 755).
Also installing Django with svn is discussed in the
official Django documentation .
After installing Django, you need to copy the files of your project to the server (via svn or simply copying via ssh or ftp; you should also add an individual user to the system who will own these files) and dump the database, and then adjust the database settings in the file .py (meaning that MySQL is already installed and configured, the database and the user are created, all data is in place - these things are far beyond the scope of this article).
Now try running the Django development server from the project directory.
python manage.py runserver 127.0.0.1:8000
On CentOS 5 there will be an error message “Error loading MySQLdb module”.
The version of MySQL-python in the CentOS distribution is too old to run a fresh svn version of Django, so you need to compile it from source.
MySQL-python cd / usr / local / src
wget http://garr.dl.sourceforge.net/sourceforge/mysql-python/MySQL-python-1.2.2.tar.gz
tar xvzf MySQL-python-1.2.2.tar.gz
cd mysql-python-1.2.2
To build MySQL-python, gcc, python-devel and mysql-devel packages will be needed.
yum install gcc
yum install python-devel
yum install mysql-devel
cd /usr/local/src/MySQL-python-1.2.2
python setup.py build
python setup.py install
Done, MySQL-python is installed as an .egg file in the site-packages directory.
Try running python manage.py runserver 127.0.0.1:8000 again and see if there are any errors. For example, I use ImageField in my project, so I had to additionally install the Python Imaging Library (yum install python-imaging).
If there are no errors, you should change 127.0.0.1 in the runserver command to the IP address of your server and test the operation of the site using a browser, but you need to open port 8000 in CentOS firewall or temporarily disable the firewall (or you can just turn off Apache and launch Django development server on port 80).
If there are no errors, then it's time to turn off the Django development server and configure Apache.
mod_pythonConfiguring Apache with mod_python to work with Django is simple: just follow the instructions from the
official Django documentation .
One note: since MySQL-python is installed as an egg package, it is important to create a temporary directory (set 777 permissions on it) for caching .egg and point to it in httpd.conf
<Location "/">
...
SetEnv PYTHON_EGG_CACHE / var / tmp / egg
</ Location>
And do not forget to restart Apache after changing httpd.conf:
/etc/init.d/httpd restart
Now the site should work through Apache on the usual http-port. Check out the browser.
memcachedEnabling caching of memcached is very important for increasing performance. Unfortunately, memcached is not in the CentOS repositories, so again you have to compile from source. This section of the article is based in part on
this HOWTO .
First you need to install libevent:
cd / usr / local / src
wget http://monkey.org/~provos/libevent-1.4.2-rc.tar.gz
tar xvzf libevent-1.4.2-rc.tar.gz
cd libevent-1.4.2-rc
./configure
make
make install
vi /etc/ld.so.conf.d/libevent.conf
## add a line:
/ usr / local / lib /
ldconfig -v
Then memcached itself:
cd / usr / local / src
wget http://danga.com/memcached/dist/memcached-1.2.5.tar.gz
tar zxvf memcached-1.2.5.tar.gz
cd memcached-1.2.5
./configure
make
make install
cp scripts / memcached.sysv /etc/init.d/memcached
ln / usr / local / bin / memcached / usr / bin / memcached
/etc/init.d/memcached start
chkconfig memcached on
Finally, you need to install libmemcache and cmemcache (python extension for libmemcache):
cd / usr / local / src /
wget http://people.freebsd.org/~seanc/libmemcache/libmemcache-1.4.0.rc2.tar.bz2
bunzip2 libmemcache-1.4.0.rc2.tar.bz2
tar xf libmemcache-1.4.0.rc2.tar
cd libmemcache-1.4.0.rc2
./configure
make
make install
cd / usr / local / src /
wget http://gijsbert.org/downloads/cmemcache/cmemcache-0.91.tar.bz2
bunzip2 cmemcache-0.91.tar.bz2
tar xf cmemcache-0.91.tar
cd cmemcache-0.91
python setup.py install
Enable memcached caching in your project’s settings.py
CACHE_BACKEND = 'memcached: //127.0.0.1: 11211 /'
(if you need more information, look in the
official Django documentation ) and restart Apache.
To get even more performance, you need to give static files not with Apache, but with a less resource-intensive server - lighhtpd.
lighttpdAgain, install from source.
cd / usr / local / src
wget http://www.lighttpd.net/download/lighttpd-1.4.19.tar.bz2
bunzip2 lighttpd-1.4.19.tar.bz2
tar xf lighttpd-1.4.19.tar
cd lighttpd-1.4.19
yum install glib2-devel openssl-devel pcre-devel bzip2-devel gzip-devel
./configure
make
make install
cp doc / rc.lighttpd.redhat /etc/init.d/lighttpd
chkconfig lighttpd on
mkdir / etc / lighttpd
cp doc / lighttpd.conf / etc / lighttpd /
And now you need to configure Apache and lighttpd so that the static files are given to lighttpd (on port 80), and the rest of the requests are serviced by Apache on port 81 (thanks to
nolancaudill.com for this solution):
- Configure Apache for port 81: find
Listen 80 and replace with Listen 127.0.0.1:81. Also, do not forget to change the port number in all VirtualHost directives. Restart Apache.
- Edit /etc/lighttpd/lighttpd.conf. Remove comments from the 'mod_alias' and 'mod_proxy' modules and add lines (correct for your needs):
$ Http ["host"] == "yourdomain.com" {
# here we are mapping / media / for admin media
# and / static / for the standard media_url
alias.url = (
"/ media /" => "/usr/lib/python2.4/site-packages/django/contrib/admin/media/",
"/ static /" => "/var/www/html/media.yourdomain.com/",
)
$ HTTP ["url"]! ~ "^ / (Static | media) /" {
proxy.server = ("" => (("host" => "127.0.0.1", "port" => 81)))
}
}
Also change the server.document-root to “/ var / www / html /” and create a symbolic link “/var/www/html/media.yourdomain.com/” pointing to the media directory of your project.
And at the end some more performance tips: