RHEL, CentOS 5 Installation Guide

Software Dependencies

OSQA is a Python/Django/WSGI application, all of which are missing (at least in usable form) in a CentOS 5 distribution.


CentOS 5 has python 2.4, and OSQA (or rather Django) likes 2.6+.

Upgrading the version of Python on CentOS is to be avoided, since core system tools (e.g yum) depend on Python, and you don't want to risk breaking those, so you want to install a newer version of Python in a separate location.

Download a recent version of Python 2.x from https://www.activestate.com/activepython/downloads, expand the .tgz into a temp directory and run the installer, accepting the default installation path (/opt/ActivePython-2.x. This will create a separate installation, without breaking the core system Python.

[root@server ActivePython-]# ./install.sh
Enter directory in which to install ActivePython. Leave blank and
press 'Enter' to use the default [/opt/ActivePython-2.6].
Install directory: 
Installing ActivePython to '/opt/ActivePython-2.6/

Whenever python is referenced from in this document, it refers to this later version of Python, so refer to it explicitly or modify your PATH.

Required Python Modules

Using the easy_install command in the new Python installation directory, install the following modules:

[root@server /]# cd /opt/ActivePython-2.6/bin/
[root@server bin]# ./easy_install ElementTree
[root@server bin]# ./easy_install Markdown
[root@server bin]# ./easy_install html5lib
[root@server bin]# ./easy_install python-openid

python-openid is only required if you plan to enable OpenId authentication.


Download the latest stable version of Django from http://www.djangoproject.com/download/.
Expand the distribution archive and run the setup.py script using your new version of Python - this will install Django into that Python installation.

[root@server Django-1.2.1]# /opt/ActivePython-2.6/bin/python ./setup.py install


Download a recent version of mod_wsgi from http://code.google.com/p/modwsgi/downloads/list.
Expand the archive, configure, make and install the module.

To build mod_wsgi you'll need a standard build toolchain (gcc, autoconf, automake etc.), as well as the httpd-devel package installed. Use yum to install these if they're not present.

When you run the configure script, you need to point it at the new installation of Python you created previously.

[root@server mod_wsgi-3.2]# ./configure --with-python=/opt/ActivePython-2.6/bin/python
checking for apxs2... no
checking for apxs... /usr/sbin/apxs
checking Apache version... 2.2.3
configure: creating ./config.status
config.status: creating Makefile
[root@server mod_wsgi-3.2]# make
[root@server mod_wsgi-3.2]# make install

If you get an apxs: command not found error during the configure, you've forgotten to install httpd-devel.

Modify your Apache configuration to load the mod_wsgi module.
Either add the following directive to /etc/httpd/conf/httpd.conf (with all the other LoadModule directives) or in a new mod_wsgi.conf file in /etc/httpd/conf.d/.

LoadModule wsgi_module modules/mod_wsgi.so

You'll need to restart Apache to get the module to load (you can leave this until later, as you'll be modifying other Apache config):

[root@server /]# service httpd restart

OSQA Installation


Create an OSQA directory, and checkout the latest version from SVN into it.

[root@server /]# cd /opt
[root@server opt]# mkdir OSQA
[root@server opt]# cd OSQA
[root@server OSQA]# svn co http://svn.osqa.net/svnroot/osqa/trunk .

Create Databases and Modify Permissions

There are multiple ways you could do this - the key thing is that the Apache user account can read your entire OSQA directory tree, and can write to the appropriate folders.

Create the missing cache directory:

[root@server OSQA]# mkdir cache

This directory is used by the Django caching system, configured by the CACHE_BACKEND property in settings_local.py as you'll see later.

Make sure the entire OSQA install tree is readable by the apache user account.

[root@server OSQA]# chown -R apache:apache .

Make sure some of the key directories are writeable:

[root@server OSQA]# chmod u+w cache
[root@server OSQA]# chmod u+w log
[root@server OSQA]# chmod u+w forum/upfiles

If you plan to use the embedded sqlite database, then create a directory for the database files:

[root@server OSQA]# mkdir db
[root@server OSQA]# chown apache:apache db
[root@server OSQA]# chmod u+w db

Configure OSQA WSGI module

Copy the osqa.wsgi.dist file to osqa.wsgi and modify to match your installation:

import os
import sys
os.environ['DJANGO_SETTINGS_MODULE'] = 'OSQA.settings'
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()

There are three key things here:

  • Both paths are required for things to work
  • The 2 paths you want are the OSQA directory (the one with settings.py in it)) and the parent directory of that
  • The name of your DJANGO_SETTINGS_MODULE needs to match your OSQA install directory - i.e. 'OSQA.settings' for /opt/OSQA

Configure OSQA

Copy the settings_local.py.dist file to settings_local.py and modify to match your installation.
In particular you need to:

  • Configure the database settings (embedded sqlite use is shown below)
  • Modify the APP_URL (otherwise links in emails will be broken)
  • Configure the DISABLE_MODULES to turn of things you don't want (like Facebook auth etc.).

The main OSQA installation guide has more details on this file, and what each of the modules do.


DATABASE_NAME = '/opt/OSQA/db/osqa.db'             # Or path to database file if using sqlite3.
DATABASE_USER = ''               # Not used with sqlite3.
DATABASE_PASSWORD = ''               # Not used with sqlite3.
DATABASE_ENGINE = 'sqlite3'  #mysql, etc


APP_URL = 'http://your.server.com' #used by email notif system and RSS


DISABLED_MODULES = ['books', 'recaptcha', 'project_badges', 'oauthauth', 'facebookauth']

Using PostgreSQL

If you're going to be using PostgreSQL (which is a good option as it support full text searching) you'll need to do a few extra things.

PostgreSQL Full Text Search

If you want to use PostgreSQL full text searching, make sure that you are using PostgreSQL 8.3 or later.

By default CentOS 5 comes with PostgreSQL 8.1, but it also provides packages for PostgreSQL 8.4.
If you want to enable the PostgreSQL full text search module, you need to install the 8.4 version or get access to a server running a later version.

Installing and configuring PostgreSQL is beyond the scope of this guide (there are plenty of good guides on the interweb) - but you need a server setup that allows access from the OSQA server (either localhost or remote) using password authentication (i.e. md5 auth).

If you must use PostgreSQL < 8.3, then you'll need to edit settings_local.py and add 'pgfulltext' to the list of DISABLED_MODULES. If you don't do this, then searching will not work.

If you decide to use PostgreSQL 8.3 and the pgfulltext module, then you'll need to edit settings_local.py and add 'sphinxfulltext' to the list of DISABLED_MODULES instead. (Sphinx is another FTS module that may interfere with the pgfulltext module).

Configuring PostgreSQL

You'll need your PostgreSQL admin to create a database and user account for you. The user account should be the database owner (so you can use the manage.py syncdb tools below:

[root@server OSQA]# createuser -P uosqa
Enter password for new role: 
Enter it again: 
Shall the new role be a superuser? (y/n) n
Shall the new role be allowed to create databases? (y/n) n
Shall the new role be allowed to create more new roles? (y/n) n
[root@server OSQA]# createdb -O uosqa osqa

You will need to ensure the postgresql-devel package is installed, or the installation of the PostgreSQL database adapter in the next step will fail:

[root@server /]# yum install postgresql84-devel

Install the PostgreSQL database adapter in your new Python installation:

[root@server /]# cd /opt/ActivePython-2.6/bin/
[root@server bin]# ./easy_install psycopg2

In your OSQA directory, modify settings_local.py to use the new database you created, and the PostgreSQL database engine you've installed:


DATABASE_NAME = 'osqa'             
DATABASE_USER = 'uosqa'            
DATABASE_ENGINE = 'postgresql_psycopg2'
DATABASE_PORT = ''                         # Leave blank to use default port


If you're doing this after you've got OSQA up and running, you will need to repeat the Create Database Tables step to create the database tables and restart Apache after making the changes.

Create Database Tables

[root@server OSQA]# /opt/ActivePython-2.6/bin/python manage.py syncdb

Answer no to creating a superuser (the first account you create in OSQA will become that).

If you decide to enable OpenId (or other modules) after doing this, you'll need to re-run the command to create new tables.

If you're using PostgreSQL 8.3+ and have the pgfulltext module enabled, then index tables, functions and triggers will automatically be created to support full text searching during the syncdb process.

Apache Integration

Create Directories

These directories are required for the Python/Django/WSGI stack to play nice:

[root@server /]# mkdir -p /var/run/wsgi
[root@server /]# mkdir -p /var/python/eggs

You can also create a separate directory under /var/log/httpd for the OSQA site logs:

[root@server /]# mkdir /var/log/httpd/OSQA

If you don't want to do this, just use a different log file path in the Apache site config below.

Apache Configuration

Create an osqa.conf file in /etc/httpd/conf.d and modify it to match your installation:

WSGISocketPrefix run/wsgi
WSGIPythonHome /opt/ActivePython-2.6
WSGIPythonEggs /var/python/eggs

#NOTE: all urs below will need to be adjusted if
#settings.FORUM_SCRIPT_ALIAS !='' (e.g. = 'forum/')
#this allows "rooting" forum at [http://example.com/forum], if you like
Listen 8082
<VirtualHost *:8082>
        ServerAdmin admin@your.server.com
        DocumentRoot /opt/OSQA/forum
        ServerName your.server.com

        #run mod_wsgi process for django in daemon mode
        #this allows avoiding confused timezone settings when
        #another application runs in the same virtual host
        WSGIDaemonProcess OSQA
        WSGIProcessGroup OSQA

        #force all content to be served as static files
        #otherwise django will be crunching images through itself wasting time
        Alias /m/ /opt/OSQA/forum/skins/
        Alias /upfiles/ /opt/OSQA/forum/upfiles/
        <Directory /opt/OSQA/forum/skins>
                Order allow,deny
                Allow from all

        #this is your wsgi script described in the prev section
        #this is your wsgi script described in the prev section
        WSGIScriptAlias / /opt/OSQA/osqa.wsgi

        CustomLog /var/log/httpd/OSQA/access_log common
        ErrorLog /var/log/httpd/OSQA/error_log

Important stuff:

  • Change the port in the Listen and VirtualHost directives as required
  • The WS* directives don't seem to like comments after them
  • WSGISocketPrefix is configured relative to /etc/httpd, so finds your /var/run/wsgi directory because of the run -> /var/run/wsgi link
  • WSGIPythonHome points at your new Python install
  • WSGIPythonEggs points at the temp directory you created previously
  • Change the CustomLog and ErrorLog paths if you don't want the logs in a separate directory - i.e. you like to have logs with distinct names, rather than per-site log directories
  • You can use some of the other config (like an HTTPS site for admin) from the OSQA and Apache guide if you like


Restart Apache, and everything should work.

When Things Go Wrong

Check the error log in /var/log/httpd/OSQA/ if things break.

If you're getting 500 errors in the OSQA web screens, then setting DEBUG = True in settings_localy.py (followed by an httpd restart) will give you a full error trace that you can use to help locate the problem (or ask for support).

Broken Stuff

  • The Django style admin interface is broken with the current config - CSS stylesheets under /admin_media are not being loaded.
Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.
  1. Dec 04, 2010

    Ron Gross says:

    Don't forget to install subversion: yum -y install subversion

    Don't forget to install subversion:

    yum -y install subversion

  2. Jul 01, 2011

    crikey says:

    The syncdb was failing for me due to symlinks. Note to self, don't use symlinks...

    The syncdb was failing for me due to symlinks. Note to self, don't use symlinks for the install folder.

  3. Jan 18, 2012

    Rahul Jha says:

    Just a correction for the configuration provided for osqa.conf. In Apache2, you ...

    Just a correction for the configuration provided for osqa.conf. In Apache2, you need to declare NameVirtualHost *:8080 in order for this to work, the Listen directive doesn't work. From the Apache docs here (http://httpd.apache.org/docs/2.0/vhosts/examples.html):

    You have multiple domains going to the same IP and also want to serve multiple ports. By defining the ports in the "NameVirtualHost" tag, you can allow this to work. If you try using <VirtualHost name:port> without the NameVirtualHost name:port or you try to use the Listen directive, your configuration will not work.

    So the correct config would be:

    NameVirtualHost *:8080
    <VirtualHost *:8080>
    ServerAdmin admin@your.server.com
    DocumentRoot /opt/OSQA/forum
    ServerName your.server.com

  4. Apr 06, 2012

    Matt Janulewicz says:

    I've come across a few other quirks when following these instructions. Here is h...

    I've come across a few other quirks when following these instructions. Here is how I solved them:

    1) If you get 'no module named site' in your http error_log, it likely means your /opt/ActivePython-n.n directory is not readable by the apache server. Do a 'chown -R apache:apache /opt/ActivePython-n.n' and it should work.

    2) If you get errors about "CsrfResponseMiddleware" in your apache error_log, it means you are using too new of a Django. Be sure you download the 1.3.1 tarball and build that. If you have to re-build this, make sure you also rebuild mod_wsgi afterward.

    3) General compatibility issues. If you use the latest ActivePython (2.7), you'll need these, too:


    • That is, if you are using mysql. You'll need to download the source from Sourceforge and compile it by hand against your custom installed ActivePython in /opt