Brandon Konkle
Brandon Konkle

Principal Engineer, type system nerd, Rust enthusiast, supporter of social justice, loving husband & father, avid comic & manga reader, 日本語を勉強してる。

I’m a Software Architect with more than 15 years of experience creating high performance server and front-end applications targeting web and mobile platforms, & today I lead a team at Formidable Labs.



My Django Development, Testing, and Production Environments

I've seen a lot of discussion lately about different strategies for developing and deploying Django applications. I wanted to share my current environment in the hopes that it might help someone new to Django or software development in general, and I was also hoping for some constructive criticism so that I can learn best practices. Most of my coding is done on my own, but I've been trying to stay away from cowboy coding habits as much as possible to keep my development practices disciplined.

I started out using Gedit with plugins and the Linux command shell, and that worked very well. As my projects grew larger, though, I really wanted a more feature-rich environment that would allow tighter integration of Subversion. I also did a small amount of development on a Windows machine (not by choice), and I wanted a development environment that I could use across multiple platforms. I settled on Eclipse after a lot of experimentation, and so far I've really enjoyed it.

My Development Environment

To start out with, I'll talk a little about my development environment. I use an Ubuntu laptop and desktop for development, switching back and forth depending on how I feel at the moment. The desktop is custom-built, and the laptop is from HP. They are both dual-core amd64 machines, and I've been very happy with how Linux support for the amd64 architecture has progressed.

I use the Eclipse Ganymede classic download with the Aptana, PyDev, and Subclipse plugins. The reason I use the classic download instead of the standalone Aptana Studio is twofold, actually. First, there's no amd64 version of the standalone Aptana download yet. Secondly, on the Windows machine I've noticed better compatibility with Eclipse classic for some of the other minor plugins I've tried out. I believe Aptana's standalone software is currently running Eclipse 3.2, and a few of the plugins I tried needed 3.3 or better.

For version control, I use Subversion. I host my own subversion server on my testing machine, which I'll talk more about in a moment. I organize my repository with the customary trunk, branches, and tags folder in the root of the repository. Under branches, I keep a separate testing branch and production branch for those environments. For each project in my repository, I have a directory underneath trunk. In each project directory, I have a templates and static directory. When I want to test or deploy changes, I merge the revisions I want from trunk to one of my branches.

Under the home directory on my development machines, I have a full checkout from SVN including all the branches. Then, using symlinks I mirror the directory layout that my production host, WebFaction, uses. For this layout, I have a top-level webapps directory. Underneath that I have a django directory which I add to my PYTHONPATH, and a static directory to house symlinks to each project's static content. I do this so that each site also has access to “shared” static content including common JS files, a reset stylesheet, etc. In my templates, “/static/project/” points to the project-specific files and “/static/shared/” points to the shared media.

In the django directory, I symlink all of my project directories from my SVN checkout, including a project I call plugins which includes svn:externals links to several third-party apps. I also include Django itself as an external there.

When I develop, I always svn update first to syncronize my checkout, and then I use the built-in Django development server. I have PostgreSQL installed on each development machine, and I use pg_dump dbname > dump.sql from the production server and then psql dbname < dump.sql on the development machine when I need a fresh copy of the database for an existing site.

My Testing Environment

For testing, I use a separate custom Ubuntu machine running a single-core 32-bit AMD processor. In my home directory I have just the testing branch checked out, and again I mirror my production environment through symlinks. The SVN repository is hosted on this machine, and I will soon be implementing periodic backups. I also host Trac from this machine for project management. To reach the machine remotely, I've set up DNS overrides with my production host. I'm planning on a cron script that will update the IP address periodically with WebFaction since my IP address changes every time I lose my connection to my ISP (mainly due to infrequent power outages).

I run PostgreSQL for the database and Apache for the webserver, using mod_python for interaction with Django. I have a VirtualHost set up for testing, and I add each site as a Location under that VirtualHost. That way each testing site sits under the testing domain as a root directory, such as and

My Production Environment

For production, as I mentioned before, I use WebFaction. It allows Linux shell access through SSH, and they have a helpful library of knowledge-base entries and forum posts that have really made them easy to use. I have a checkout of just the production branch under my home directory, and then I use symlinks within their directory structure to set up the environment.

In the panel, I have a django application installed and a static application installed, which adds those directories under the webapps directory. The django directory also includes the Apache configuration files and a Python site-packages directory. From the site-packages directory, I've removed django and use the svn:external for Django from my plugins project. I have each separate site set up as a VirtualHost entry in the Apache conf.

When I am ready to make changes in the production environment, I'll merge them to the production branch on my development machine and make sure there are no conflicts. My production branch already has the production settings (such as DEBUG = False) and my merges don't change that. Once I resolve any conflicts, I commit the production branch and then SSH into the production server to do an svn update under the checkout directory. I run python2.5 syncdb and whatever else I need to do in the command line under my project, and then restart the Apache server. From there, I fire up Firefox and check to see if everything worked.

So far this setup has served me well, but I'm very open to suggestions or questions. Please feel free to post comments to discuss.

I’m a Software Architect with more than 15 years of experience creating high performance server and front-end applications targeting web and mobile platforms, & today I lead a team at Formidable Labs.

View Comments