ByteFlow + Apache HowTo

When searching for an engine for this brand new blog site I’ve come across ByteFlow. It immediately appealed to me, because:

  • it’s written in Python, language that I like a lot and use a lot.
  • it’s based on Django, framework that I used on one of my past projects.
  • seems to have a rich feature set and is being actively developed

On the other hand it’s relatively new and (therefore?) doesn’t come with an overwhelmingly extensive documentation. For start, installation wasn’t a piece of cake. First I tried to run ByteFlow with lighttpd, following a howto on Benjamin Smith’s blog, but ended up with a little problem I didn’t manage to solve. Not knowing much about lighttpd I eventually switched to Apache that I’m pretty familiar with.

The ByteFlow people recommend Apache with mod_wsgi as the best way to run their engine, however information on how to do that are pretty sparse. If you also wonder how read on, I’ll document my setup here. Perhaps you’ll find some useful hints in here.

Required packages

My server runs CentOS 5, which is 99% the same as RedHat Enterprise Linux 5 without the massive price tag attached. I tend to use vendor-provided packages instead of compiling stuff manually where possible. It makes ongoing maintenance much easier. Therefore I’m bound to use httpd 2.2.3, python 2.4.3, mysql 5.0.45 and subversion 1.4.2 as that’s what comes with CentOS 5. Additionally I added EPEL repository to my yum repo list and installed mod_wsgi 2.1 and mercurial 0.9.3. That’s about it for base packages.

ByteFlow however requires some additional Python modules, see its install page for more details. Fortunately EPEL has most of them available: python-imaging, python-openid and python-elementtree.

One little issue I had with MySQLdb — the version found in CentOS is MySQL-python 1.2.1 while Django apparently requires version 1.2.1_p2 or higher. As I said I like to have things packaged so I built an updated RPM myself (download MySQL-python-1.2.1_p2-0_mludvig.i386.rpm).

One last prerequisite is BeautifulSoup module, a HTML parser for Python. It doesn’t come in a package but since it’s just one single stand alone file I didn’t care and simply copied it to the byteflow directory as we’re gonna see later.

Getting Django and ByteFlow

All the resources and files specific to this blog’s vhost will be placed in a dedicated directory. For instance create /www/hintshop, to make our examples shorter.

Both Django and ByteFlow are so new that they are not available as RPM packages for CentOS. Yet. Our best choice is therefore to grab them from their respective source repositories. Go to /www/hintshop and become root or any other user that has write access in there. The run these two commands:

/www/hintshop# svn  co  http://code.djangoproject.com/svn/django/branches/releases/1.0.X  django
[...]
A    django/examples/urls.py
A    django/setup.cfg
 U   django
Checked out revision 9675.

/www/hintshop# hg clone http://hg.piranha.org.ua/byteflow
destination directory: byteflow
[...]
updating working directory
557 files updated, 0 files merged, 0 files removed, 0 files unresolved

That should have created two directories: django and byteflow respectively. We’ll need two more though:

/www/hintshop# mkdir -p etc www/media www/download

/www/hintshop# ls -l
total 20
drwxr-xr-x 11 root root 4096 Dec 22 19:54 byteflow
drwxr-xr-x  9 root root 4096 Dec 19 02:17 django
drwxr-xr-x  2 root root 4096 Dec 22 20:09 etc
drwxr-xr-x  4 root root 4096 Dec 22 20:09 www

The last step here is to download BeautifulSoup.py to byteflow/ directory.

ByteFlow configuration

First of all create a database and a dedicated user account in MySQL:

~$ mysql -uroot -p
mysql> create database hintshop;
mysql> grant all on hintshop.* to 'hintshop'@'localhost' identified by 'BlahBlah';

Now in /www/hintshop/byteflow copy settings_local.py.template to settings_local.py and adjust the settings to your needs. Also have a look in settings.py and eventually override some additional settings in settings_local.py. I for instance added these two lines:

TIME_ZONE = 'Pacific/Auckland'
BLOG_URLCONF_ROOT = ''

Don’t forget to comment out DEBUG=True and the following print statement near the end of the config file. Finally run ./manage.py syncdb to initialise the database.

Apache + mod_wsgi configuration

Here the fun stuff begins. For security reasons I like to have different websites run under separate user accounts. So I created a new user hintshop dedicated for running this blog.

Next create a wsgi wrapper script and save it as /www/hintshop/etc/byteflow-wsgi.py:

#!/usr/bin/python

import os, sys
sys.path.append('/www/hintshop/django')
sys.path.append('/www/hintshop/byteflow')
os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'

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

And finally create a new Apache Virtual Host for the blog. In my case it’s file /etc/httpd/conf/vhosts.conf:

<VirtualHost *:80>
ServerName      hintshop.ludvig.co.nz

Alias           /media/         /www/hintshop/www/media/
Alias           /download/      /www/hintshop/www/download/
Alias           /static/        /www/hintshop/byteflow/static/
Alias           /admin-media/   /www/hintshop/django/django/contrib/admin/media/

WSGIDaemonProcess       site-hintshop user=hintshop group=hintshop threads=5
WSGIProcessGroup        site-hintshop
WSGIScriptAlias         /        /www/hintshop/etc/byteflow-wsgi.py

ErrorLog        logs/hintshop-error_log
CustomLog       logs/hintshop-access_log combined
</VirtualHost>

Now restart Apache with service httpd restart and provided you've got a domain name properly set up you're ready to blog :-)

Let me know if you find any error or omission in this howto. Thanks!