John Woltman's
Attempt to Stay Current at Bleeding Edge Blog Technology

Installing GeoDjango with PostGIS on CentOS 6.5

Posted Feb. 13, 2014 by John Woltman

Django includes a useful geographic services system called GeoDjango.  Getting it up and running on CentOS can be a chore, particularly if you need packages newer than CentOS 6 provides.  In this post, I'm going to list the steps I took install GeoDjango with PostgreSQL's PostGIS system.  If you're reading this, then I'm going to assume you have at least a passing familiarity with Linux and Django.

Goals

I want to use the latest software packages, something that CentOS isn't well known for.  Specifically, I want the latest Django, PostgreSQL, and PostGIS.  Different Django projects may require different versions of 3rd party packages, so I also I want the Django/Python stuff in its own virtual environment.  I want as much of the software to be updateable through yum or pip as possible, so I tried to stick to official repositories and PyPI packages when I could.

The patch number of the software shouldn't matter for my purposes.  Here are the current versions at the time I am writing:

Software Version
PostgreSQL 9.3.2
PostGIS 2.1.1
Python 2.7.6
Django 1.6.2

Three Notes About Security:

  1. The passwords I use are bad passwords - they are for example use only.
  2. You can (and should) configure Postgres to be more secure.  Again, this configuration is for example use only.
  3. I installed almost everything logged in as root (via su -).  This is a bad habit.  Again: EXAMPLE!

Setting up CentOS

I used the netinstall ISO for 64-bit CentOS so that I could feel like I was making progress immediately.  I accepted the defaults whenever possible.  Some customizations:

  1. Source was http://mirror.centos.org/centos/6/os/x86_64/
  2. Hostname set to geotest.
  3. Package selection was set to Minimal Desktop.
  4. Root's password was set to password.
  5. Username set to jdoe with password password.

After the installation, I set up the VirtualBox guest additions.  Be sure to update the kernel and and install some required packages first:

yum -y update kernel
yum -y install gcc gcc-c++ kernel-headers kernel-devel dkms
reboot

Now you can install the guest additions.  Reboot again after they're installed.

Configuring PostgreSQL

Install PostgreSQL and PostGIS

We're going to use the official Postgres yum repositories so that we can easily install PostgreSQL 9 instead of the CentOS-supplied version 8.  PostGIS is also available through the PG repo, so we'll install that too.

Before you start, add exclude=postgresql* to the [base] and [updates] sections of /etc/yum.repos.d/CentOS-Base.repo.  This prevents us from accidentally installing the CentOS PG packages.

# Enable the PostgreSQL and EPEL repos
yum -y install http://yum.postgresql.org/9.3/redhat/rhel-6-x86_64/pgdg-centos93-9.3-1.noarch.rpm
yum -y install http://download.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm

# Install PostgreSQL, PostGIS, and the required support packages
yum -y install postgresql93-server postgis2_93-client postgresql93-devel gdal-devel

# Initialize & start the database
service postgresql-9.3 initdb
service postgresql-9.3 start

# Set PostgreSQL to auto-start at boot time
chkconfig postgresql-9.3 on

Create A Geospatial Database

Now we'll use the psql program to create a database with geospatial extensions, i.e. PostGIS.

su - postgres
createdb geodb

# Add the PostGIS features to the database
psql -d geodb -c "CREATE EXTENSION postgis;"
psql -d geodb -c "CREATE EXTENSION postgis_topology;"

# Grant our user access to the database
psql -d geodb -c "CREATE ROLE jdoe LOGIN;"
psql -d geodb -c "GRANT ALL ON DATABASE geodb TO jdoe;"

Verify PostGIS is enabled for your database with: psql -d geodb -c "SELECT postgis_lib_version();".  Here's the results the command gave me:

 postgis_lib_version 
---------------------
 2.1.1
(1 row)

If the above query results in an error, I don't know what happened and you should give up on computers.

Installing Python

Since CentOS uses Python 2.6 for important system tools, we don't want to clobber the default Python.   I based my process on this excellent post at Too Much Data.    Here are the commands I used:

# We need some other packages installed before we build Python
yum -y groupinstall "Development Tools"
yum -y install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gdbm-devel db4-devel

# Download and install Python
wget http://python.org/ftp/python/2.7.6/Python-2.7.6.tgz
tar xzf Python-2.7.6.tgz
cd Python-2.7.6
./configure --prefix=/usr/local --enable-shared LDFLAGS="-Wl,-rpath /usr/local/lib"
make

# Make sure you use altinstall, or you'll overwrite the system python
make altinstall

The command python2.7 should now be available.  Let's keep installing packages for Python:

wget https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py -O - | python2.7

easy_install-2.7 pip virtualenv

Set up a Python Virtual Environment

Django projects are, like most software, easier to develop and deploy when you keep a tight reign on their configuration.  A virtual environment ("virtualenv") will keep your reliance on system Python packages to a minimum.  You will be able to install specific versions of each package in a virtualenv, without needing special permissions and without trampling on the system packages.

Up until now I've been executing everything as root.  The rest of this guide should be executed with normal user privileges, such as my jdoe example account.  We told PostgreSQL to allow a user called "jdoe" access to the database, so these examples won't work as root.

Basic virtualenv

It is simple to start a new virtualenv.  We'll make one called vegeo.

# Create the virtualenv
virtualenv vegeo

# Activate it
source vegeo/bin/activate

# Add the path to PostgreSQL's binaries to the path, because PsycoPG2's install will fail if it cant find them
export PATH=/usr/pgsql-9.3/bin:$PATH

# Install NumPY, PsycoPG2, and, for convenience, iPython
pip install numpy psycopg2 ipython django

Installing GDAL

Installing the Python GDAL package is more involved.  The version of GDAL installed by the PostgreSQL repo is 1.9.  The latest GDAL on PyPI is 1.10, so we need to download the older version.  We also need to use a specific command to build it because GDAL's setup.py is broken.

wget http://pypi.python.org/packages/source/G/GDAL/GDAL-1.9.1.tar.gz

tar xzf GDAL-1.9.1.tar.gz

cd GDAL-1.9.1

python setup.py build_ext $(gdal-config --cflags) install

Start a Django Project

You are now ready to start a Django project.  You'll be able to use GeoDjango and get all of the geospatial goodness it offers.  I have posted a small proof-of-concept Django project on GitHub so you don't have to write any code:

git clone https://github.com/johnwoltman/geotest
cd geotest
./manage syncdb

# Now you can play around with GeoDjango!
./manage shell

# Start the Django server
./manage runserver

If you run the server and visit http://127.0.0.1:8000/admin/geotest/friend/ you can add a friend to the database, and the coordinates for their house using the OpenStreetMap widget.