CruiseControl Server and Django: How to Setup CruiseControl to Automatically Deploy Django Applications

In a previous article, I described how to deploy the Django based application to a server running Ubuntu Server 7.04 and Apache 2.0 running mod_python. This article intends to expand upon that configuration by adding automated deployment using CruiseControl and Subversion source control server. CruiseControl is a java based server that has the ability to monitor a variety of source control servers, such as Subversion,  for changes and execute scripts or programs for deploying and configuring an application whenever changes are detected in source control.

Installing CruiseControl requires downloading the Java 6 runtime files, downloading the CruiseControl application, and configuring which source control paths to monitor and their associated actions. My CruiseControl configuration consists of two separate ‘projects’ – one for monitoring static files and another for monitoring the Django application itself.

First install the Java 6 runtime and JDK files. You can do this by typing:

sudo apt-get install sun-java6-bin sun-java6-jre sun-java6-jdk

Before downloading the CruiseControl application, I created a separate user account , called ‘deploy’, for monitoring and executing deployments. This created a separate home directory for the user and alleviated any worries about permissions  or ownership that may affect directory or file access.

You can create a new user called ‘deploy’ and add it to the administrative group by typing the following:

sudo adduser deploy
sudo adduser deploy admin

After creating the new user account, log into the new account and download CruiseControl. Type:

wget http://superb-west.dl.sourceforge.net/sourceforge/cruisecontrol/cruisecontrol-bin-2.7.zip

Unzip CruiseControl by typing

unzip cruisecontrol-bin-2.7.zip 

Since this is a java application, the only thing required for installation is a directory for the java files to live in. In my configuration, I renamed the CruiseControl directory from ‘cruisecontrol-bin-2.7’ to ‘cc’. Type:

mv cruisecontrol-bin-2.7 cc

My path for CruiseControl now looks like this: ‘/home/deploy/cc’

If you haven’t yet, you need to add the JAVA_HOME path variable to your account. You can do this by editing the ‘.profile’ file in the current user’s home directory. I did this by typing:

vi ~/.profile

After opening the file, scroll to the very end of the file and append the following text:

JAVA_HOME="/usr/lib/jvm/java-6-sun-1.6.0.00/jre"

export JAVA_HOME

This will add the JAVA_HOME path variable. The variable should be set to the location of the java-6 jre subdirectory. In order for these changes to take place, you need to re-login into your account.

After logging into your account again, go to the directory where you extracted CruiseControl and run the CruiseControl shell script. I did this by typing:

sh cruisecontrol.sh

This initiates CruiseControl for the first time and allows the server to test itself against an example project that comes with the default installation. If you see a few errors related to accessing an Subversion repository, don’t worry about it.

After the confirming that the server works, stop the server by killing the process. I did this by finding the pid in the ‘/home/deploy/cc/cc.pid’ file. Type:

cat cc.pid
sudo kill PID_NUMBER

In the following text, we’re going to configure CruiseControl to deploy a Django application. First, let’s remove the example project (which is called ‘connectfour’) and replace it with a Django deployment project and a project for deploying static files. In the previous article, I created two separate deployment locations – one called ‘assets’, which stores static files, and another called ‘ALEXKUO’, which is the Django Application.

The CruiseControl project names will be ‘assets’ and ‘webapp’. In your CruiseControl directory [‘/home/deploy/cc’], type:

cd projects
rm -rf connectfour
mkdir assets
mkdir webapp

The projects directory will contain the Python scripts used to delete and re-checkout files from Subversion. We also need to setup the logs directory. In your CruiseControl directory [‘/home/deploy/cc’], type:

cd logs
rm -rf connectfour
mkdir assets
mkdir webapp

Next we need to edit the CruiseControl configuration file or ‘/home/deploy/cc/config.xml’. To open type:

vi config.xml

My configuration file looks like the following:

<cruisecontrol>
<project name="webapp">

<bootstrappers>

<currentbuildstatusbootstrapper file="logs/webapp/buildstatus.txt"/>

</bootstrappers>


<modificationset quietperiod="10">

<svn RepositoryLocation="http://svn.alexkuo.info/trunk/ALEXKUO" />

</modificationset>


<schedule interval="30">

<exec workingdir="/home/deploy/cc/projects/webapp"

command="python"

args="deploy.py" />

</schedule>


<listeners>

<currentbuildstatuslistener file="logs/webapp/buildstatus.txt"/>

</listeners>


<publishers>

<currentbuildstatuspublisher file="logs/webapp/buildstatus.txt"/>

</publishers>

</project>

<project name="assets">

<bootstrappers>

<currentbuildstatusbootstrapper file="logs/assets/buildstatus.txt"/>

</bootstrappers>


<modificationset quietperiod="10">

<svn RepositoryLocation="http://svn.alexkuo.info/trunk/assets" />

</modificationset>


<schedule interval="30">

<exec workingdir="/home/deploy/cc/projects/assets"

command="python"

args="deploy.py" />

</schedule>


<listeners>

<currentbuildstatuslistener file="logs/assets/buildstatus.txt"/>

</listeners>


<publishers>

<currentbuildstatuspublisher file="logs/assets/buildstatus.txt"/>

</publishers>

</project>
</cruisecontrol>

As you can see from my config.xml file, the project tag defines a unique project. Each project monitors a specific repository location for changes. These repository locations are defined by the ‘modificationset’ and ‘svn’ tags. Whenever changes are detected, the schedule and exec tags are activated. The publishers, listeners, and bootstrappers files are log files that record activity during monitoring, building, and deployment.

The ‘deploy.py’ files contains a python script for deleting a target directory and re-checking out files from a target SVN location. Let’s create these files.

For the webapp project, create a file call ‘deploy.py’ in the ‘/home/deploy/cc/projects/webapp’ directory. I did this by typing:

touch /home/deploy/cc/projects/webapp/deploy.py

Next, let’s edit this file. In the ‘/home/deploy/cc/projects/webapp’, type:

vi deploy.py

My deploy.py for the webapp looks like this:

from os import system, fchdir, getcwd
from shutil import copy, rmtree

import os

DJANGO_APP_DIR = '/home/deploy/django/django_projects/ALEXKUO'

SVN_ROOT = 'http://svn.alexkuo.info/trunk/'
SVN_APP = 'ALEXKUO'

APP_SETTINGS = '/home/deploy/django/appsettings/ALEXKUO/settings.py'

CMD_SVN_CHECKOUT = 'svn co ' + SVN_ROOT

cout_app = CMD_SVN_CHECKOUT + SVN_APP + DJANGO_APP_DIR

IS_APP_UP = False

"Remove all files in App directory and check out files"
rmtree(DJANGO_APP_DIR)
system(cout_app)
if os.path.exists(DJANGO_APP_DIR):
IS_APP_UP = True

if IS_APP_UP:
copy(APP_SETTINGS, DJANGO_APP_DIR)

The script first removes all files in the targeted Django application directory, this is done with the command ‘rmtree(DJANGO_APP_DIR)’.  I also copy a ‘settings.py’ modified for the server because the Django configuration between my local development box and public server is different. The SVN checkout is initiated with the command ‘system(cout_app)’.

Next let’s create the deploy script for the asset files. In the ‘/home/deploy/cc/projects/assets’ directory, type:

touch deploy.py

Now let’s edit this file by typing:

vi deploy.py

My deploy.py for the assets project looks like this:

from os import system, fchdir, getcwd
from shutil import copy, rmtree

import os

ASSET_DIR = '/home/deploy/websites/www.alexkuo.info/assets'

SVN_ROOT = 'http://svn.alexkuo.info/trunk/'
SVN_ASSET = 'Assets '


CMD_SVN_CHECKOUT = 'svn co ' + SVN_ROOT

cout_asset = CMD_SVN_CHECKOUT + SVN_ASSET + ASSET_DIR

"""Delete Asset directory and re checkout asset folder """
if os.path.exists(ASSET_DIR):
rmtree(ASSET_DIR)

system(cout_asset)

This python script is identical to the deploy script for the webapp, except that it excludes commands for copying the ‘settings.py’ file.

After creating your python deployment scripts, your build server should be ready for use. Turn on the server by going to the cruise control directory (/home/deploy/cc) and typing:

sh cruisecontrol.sh

You can now log off the account and your server will still be running. You can access the server’s status page by opening your browser and typing in the URL: ‘http://<server’s IP address>:8080/”

Reference

Leave a Reply