Pimping Your Trac (and Python) On TextDrive, Part I

I’m working on a new blog that I’ll actually attempt to publicize, but here’s something to get me moving in the mean time.

In this article, I’m going to present a comprehensive primer for installing and configuring Trac on a TextDrive account, though a lot of the information could be useful to anyone getting started with Trac, or running Python applications on a shared host. In Part II, we’ll extend Trac’s capabilities with some useful plug-ins.


A Preamble: What’s Trac?

Trac is a web-based tool for simplifying software project management — it’s grown to be rather popular these days, and even if you’re not familiar with it already, chances are pretty good that you’ve surfed across a Trac site at some point. If you use a version control system like Subversion for software or web development projects, Trac can provide you (or a team) with syntax-highlighted browsing of the code in your repository, diff file comparisons between arbitrary revisions, a flexible bug-tracking system, and an integrated wiki to document your project. It’s also highly extensible.

Trac is built with Python, and really, much of the set up in this article centers around setting up your own Python environment. Python is a dynamic, interpreted programming language a lot like Ruby in its elegance and efficiency, but with rather different philosophies. This setup will also set you on your way if you’re interested in web development with Python, with frameworks like Pylons, Django or Turbogears. Python is the bee’s knees, and I’ll be covering a lot more of it in the future.

The State of Affairs at TextDrive

I’ve seen a good number of questions from people out there who’ve followed TextDrive’s guide for running Trac on their shared hosting accounts, and want to get more from it. Everything here should work just fine if you’ve already set things up the TextDrive way, and I’ll cover the painless commands for upgrading your Trac environments.

You might be asking, “What’s wrong with using the instructions that TextDrive provides? Most of the work is done for you!” And you’d be right. But the version of Trac pre-installed on TextDrive’s servers is currently 0.9.6, which is beginning to show it’s age. The Trac team has been adding some really cool stuff in the 0.10 and 0.11dev branches, plus there’s a plethora of plug-ins out there that are often difficult to get working without full control over the Trac installation. So, we’re going to get to the bleeding edge!

One of the first such plug-ins that you’re likely to yearn for is WebAdmin — let’s face it, constantly logging in over SSH to modify your trac.ini or messing around with trac-admin commands to set a lot of user privileges gets old quickly. I tried in vain to get WebAdmin working on my 0.9.6 setup at TxD, and eventually scrapped it in favor rolling my own. Don’t let the length of this article fool you — it’s really not so tough, and in the end we’ll have a hot and fresh version of Trac, along with a self-contained Python environment that will make things much easier to maintain than if you were to take the pre-installed route.

There are several good reasons for opting for the development version of Trac right now: first, that aforementioned WebAdmin plug-in isn’t needed — it’s there out of the box in Trac 0.11. Second, Genshi is used as the templating system rather than ClearSilver, which was found in earlier versions. You don’t need to know anything about those at this point, except that Genshi is much easier to install. Finally, Trac 0.11 installs with Python setuptools, making it much easier to maintain, and if the final release version is out by the time you read this, Trac installation should literally be a one-liner. Let’s get started.

A Few Assumptions

I’m assuming that you’re already using Subversion to manage source code revisions on some projects. Trac can currently only operate with repositories stored on the same local system, so if you haven’t yet set it up at TextDrive, do so now using the knowledgebase articles. It’s also possible to use other version control systems with Trac, and I may cover Mercurial setup in a future article.

One other thing. The setup shown here, like that in TextDrive’s knowledgebase article, proxies tracd with Apache to publish the site. You’ll need to request a port assignment by submitting a request ticket to TextDrive support. Go do that now, so you can work on the setup while you’re waiting for a response!

Now, without further ado…

Your Own Little (Python) World

We can do all of our work over an SSH connection, so the process moves pretty quickly:

First SSH into your shell account, make a new directory for your Python environment, and fetch the virtual-python script:

$ ssh primarytxduser [at] yourhostserver [dot] com
...enter password...
$ mkdir python; cd python
$ wget http://peak.telecommunity.com/dist/virtual-python.py

This script will create a directory structure, then copy and symlink files from the existing TextDrive Python installation into your own. We won’t include the site-packages directory (where 3rd party Python libraries are stored) since TextDrive’s install contains a great many of them that we don’t need.

Then, just update some path environment variables in your shell’s config file, source it to set the values now, and you’re running with your own Python.

$ python virtual-python.py --prefix=~/python --no-site-packages
$ echo "export PYTHONPATH=$HOME/python/lib/python2.4" >> ~/.bash_profile
$ echo "export PATH=/users/home/youruser/python/bin:$PATH" >> ~/.bash_profile
$ source ~/.bash_profile
$ which python

You could just use your home directory for the prefix, but I think the python subdirectory is cleaner.

Trac Prerequisites

Now we’ll copy a few libraries from the system Python into our environment: bindings for TextDrive’s version of svn, and for the SQLite database engine (I couldn’t get my own version of pysqlite2 to build easily on FreeBSD…):

$ cd python/lib/python2.4/site-packages
$ cp -R /usr/local/lib/python2.4/site-packages/svn .
$ cp -R /usr/local/lib/python2.4/site-packages/libsvn .
$ cp -R /usr/local/lib/python2.4/site-packages/pysqlite2 .

Don’t miss the dots on each line! Symlinking instead of copying will also probably work, and save you headache if the system packages get upgraded. Now on to setuptools, which you’ll surely love for its easy_install utility. You can learn more than you ever wanted to know about setuptools and easy_install over at PEAK.

$ cd ~/python
$ wget http://peak.telecommunity.com/dist/ez_setup.py
$ python ./ez_setup.py

This will build setuptools for you and install it in your local site-packages directory. Now we can use it for the rest of the components (you don’t need to go download these!):

Only Genshi, the template language mentioned earlier, is required — the others are optional but highly recommended (and a cinch to install). Pygments is used for rendering your code as syntax-highlighted XHTML. The last two allow additional markup languages to be used for Trac’s wiki and ticketing systems. You’re probably familiar with Textile — you can use it for comments on this blog! — and docutils allows reStructuredText, an expressive wiki-like syntax commonly used in Python documentation. If you’re interested in learning more with Python, you’ll probably end up wanting docutils somewhere down the road anyway. No set-up is required for these optional components — Trac just finds them automagically. So here’s all you need to do:

$ easy_install Genshi
$ easy_install Pygments
$ easy_install docutils
$ easy_install textile

Not bad, eh? Each of these commands will produce some output as it downloads the packages, builds them as Python Eggs (a lot like Ruby’s Gems), and installs them into site-packages. Skim for any errors, but all should be OK.

Do the Damn Thing

Now we’re ready for Trac! At the time of this writing, Trac 0.11 is still in development, so we’ll need to install from an svn checkout. If the final release is out by the time you read this, you should just be able to do easy_install Trac. Yes, really. This is because Trac 0.11 is built to use our old friend setuptools, so even though we currently have to start the build manually, it’ll still produce an Egg that is easy to upgrade.

Create directories for your Trac environment(s) and the source checkout, then check out Trac trunk, build it, and install it to site-packages.

$ cd ~
$ mkdir -p trac/src; cd trac/src
$ svn co http://svn.edgewall.org/repos/trac/trunk trac-0.11dev
...checkout ouput...
$ cd trac-011dev
$ python setup.py install    # build and install Egg to site-packages

That’s it! Now you just need to create an environment associated with your svn repository. If you have an existing Trac environment from following TextDrive’s setup, you can upgrade it instead.

Create a New Environment

$ cd ~/trac
$ trac-admin <name> initenv

Use a short name. The command will run an interactive setup script to walk you through creating the environment — name your project, accept the default choices for database and repository type (just hit Return), and be sure to specify an absolute path for your repo, i.e. /users/home/youruser/svn/<repo-name>. Of course, modify appropriately if your repo is a secondary domain for your account.

Upgrade an Existing Environment

For an existing Trac environment, just run these two upgrade commands in the parent directory:

$ trac-admin <yourenv> upgrade
$ trac-admin <yourenv> wiki upgrade

And that’s it! All that’s left to do is some web server configuration, but we can play with our new toy first.

Running Trac for the First Time

By now, I’d imagine you’re eager to see this thing work. As long as you’ve gotten your port assignment from TextDrive, we have all we need to test at this point. tracd runs the Trac daemon with a lightweight web server. Fire it up!

# XXXX is your assigned port. Use tracd -h for more details.
$ tracd -p XXXX /users/home/<youruser>/trac/<yourenv>

Again, use an absolute path as shown. This runs tracd in the foreground, so you can hit CTRL+C to kill it when you’ve finished playing. Visit http://yourdomain.tld:XXXX in your browser and you should see a link with the project name you selected. It takes you to the promised land.

Getting Cozy

At this point, you could use trac-admin -h to see how to configure users and permissions, set up a cron job like the one explained below, and call it a day. But this isn’t very nice yet.

You probably don’t want to force everyone to type in that port number to reach your site, and you may want to customize the URL. We’ll also look briefly at a simple authentication set-up, in case you want to password-protect your site (like my current set-up that includes code from client projects, which is why I haven’t linked you to my own sexy spread yet).

Set Up a Custom Subdomain

We’ll address the URL first, because we’re going to set up a nicer authentication scheme in the next article anyway. This is done by proxying tracd as explained by TextDrive. To summarize the easy way, we’ll direct requests for trac.yoursite.tld to tracd using Apache mod_rewrite directives in a local .htaccess file. Basically, this is a way to give the web server specific instructions on a per-directory basis — the site root in this case. I’ll use the nano editor, ‘cause it’s friendly

$ cd ~/web/public  # or the web/public dir of a secondary domain
$ nano .htaccess   # will create the file if it doesn't exist
...file opens in nano; enter the following in the file...
RewriteEngine On
RewriteCond %{HTTP_HOST} ^trac\.
RewriteRule (.*)$1 [P]
...type CTRL-O, RETURN, CTRL-X to save and quit...

Feel free to substitute 'trac' with anything of your choosing — I use 'dev'. If you have existing rewrite rules in the file, you probably don’t need the RewriteEngine On directive, and you may want to put the other two lines above any other rules.

If you want a more sophisticated URL scheme, see the linked TextDrive document, or read up on mod_rewrite.

Simple Authentication

We’ll again refer to TextDrive’s instructions for a simple authentication setup. You can skip this for now if you can wait for Part II of this article, where I’ll show you how to set up the near-essential AccountManager plugin for Trac.

Use this command to create a password file and add the first user:

$ htdigest -c /home/<youruser>/etc/trac.digest.passwd yourdomain.tld username

Make sure you have an etc directory in $HOME — use mkdir ~/etc if necessary. username is arbitrary, but if you’re limiting access to a development team, it’d be sensible to match them with svn passwords. Omit the -c switch on subsequent calls to htdigest for the file.

You’ll need to add your users and set their permissions in the Trac environment. This is covered in Part II, but if you’re in a hurry, check tracd -h to get started, or the documentation in the wiki on your new Trac site (the manual is built in!).

To use this auth setup, you’ll need to augment the command you use to launch tracd. We’ll cover this in the next section.

Keeping tracd Up and Running

The last step for today is to make sure that tracd is run automatically when the physical server has to be restarted. For that, we need cron, the handy UNIX utility for running scheduled tasks. I’m going to use the crontab command from our login shell, which might be a little scary to some because it uses the vi text editor. vi can be a little cryptic for the uninitiated, but I’ll try to make this simple edit as painless as possible. Alternatively, you can configure cron jobs through the Webmin interface for your TextDrive account. I’ll leave that route as an exercise for the reader — it’s actually covered in the Trac setup guide I’ve linked to throughout this article. You can ignore the backslashes in these listings — just wanted to indicate the linebreaks.

$ crontab -e
...vi loads your crontab file, which might be empty...
# Press 'i' for insert mode and enter these lines
@reboot /users/home/<youruser>/python/bin/tracd -d -p XXXX \
/users/home/<youruser>/trac/<yourenv> #run tracd after reboot
# To save and exit, press ESC to enter command mode.
# Type ':wq' (for 'write quit') and hit RETURN

Be sure to replace XXXX with your port number. We set the SHELL so that cron tasks use your shell configuration, i.e. it will use your custom PYTHONPATH. It’s otherwise best to use absolute paths thoughout. The -d switch runs tracd as a daemon in the background. If you’ve set up authentication, change the reboot line above as follows. Again, see tracd -h for additional details.

/users/home/python/bin/tracd -d -p XXXX \
--auth yourenv,/users/home/username/etc/trac.digest.passwd,yourdomain.tld \

You’re all set! Just remember to actually start tracd now using whichever command you used for the cron job. Treat yourself to your beverage of choice, you’ve earned it!

Bonus: Multiple Environments

It’s possible use some sophisticated set-ups for multiple Trac environments, which are beyond the scope of this article, but there is a really simple way. You can set up additional Trac environments just as we’ve done in this article, probably for separate Subversion repositories, and serve them all up in a single tracd instance. To do this, simply specify multiple environments—separated by spaces—when you launch tracd, like this:

$ /users/home/<youruser>/python/bin/tracd -d -p XXXX \
/path/to/environ1 /path/to/environ2

Now, when you visit trac.yourdomain.tld (or whatever URL you configured), you’ll see a listing of the projects. Obviously each is an independent Trac environment, so each can have its own configuration, plug-ins, authentication, and so on.

The Next Step

A whole slew of plug-ins and other add-ons for Trac are available at Trac-hacks.org. These range from simple extensions like a Pastebin, to more complex ones like a spam filter and an extensive continuous integration system (perhaps the subject of a future article).

We’ll take a look at installing a few of those in Part II. We’ll also look at some basic environment configuration for trac.ini. Thanks for sticking it out this long!

Great, upgraded my ancient

Great, upgraded my ancient trac install using this guide… just one fix:

cd trac-011.dev should be cd trac-011dev


Great information here, and

Great information here, and it works on the new OpenSolaris hosts too.

The only additional step needed is /usr/local/lib/python2.4/site-packages/pyexpat.so needs to be copied/symlinked into the python/lib/python2.4/site-packages directory. Other than that, it works a treat.

This was a huge time saver.

Thanks for the tip, Colin.

Thanks for the tip, Colin. Great to know it’s relevant for OpenSolaris.

Post new comment

The content of this field is kept private and will not be shown publicly.
By submitting this form, you accept the Mollom privacy policy.