Django Development with Git on EC2

Rapid development and deployment is no doubt important in every phase of a product nowadays. Git is a great version control tool that streamlines the process of doing all this, but there are a few nuances to getting it to work with Django and EC2. There are a lot of tutorials online about various portions of this process, but none were fully complete in their explanations. So after spending a couple hours wrangling with this, I thought I might as well post it online in order to detail the full process.

Note: I’m using Django 1.4 and running Ubuntu 11.10 on my EC2 server and Mac OSX 10.7 on my local computer.

Part 1: Set Up Django

Assuming you already have your Django instance running correctly on your local computer, you just need to make a few changes to your settings.py file in order to make it easily run on any machine.

At the top of your file add:

import os
BASE_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), '../'))

Now go ahead and update your MEDIA_ROOT, STATIC_ROOT, STATICFILES_DIRS, TEMPLATE_DIRS to point to the appropriate subfolders where they are located. For example, you would change

STATIC_ROOT = '/path/to/myproject/static'

into

STATIC_ROOT = os.path.join(BASE_DIR, 'static')

Note: This varies for earlier versions of Django because the settings.py file is directly in the project folder and not in a separate subdirectory. In that case, use BASE_DIR = os.path.abspath(os.path.dirname(__file__)).

The next thing you’ll need to do is document the requirements needed to run your project. Pip provides a really nice and easy way to do this. Open up a terminal and enter the following:

$ cd /path/to/myproject
$ pip freeze > requirements.txt

All the required dependencies should now be declared explicitly in requirements.txt.

Part 2: Set Up Git (Local)

In your project folder, create a .gitignore file with the following contents:

*.pyc

This will avoid adding any python bytecode files to the git repository. You can also add other entries as well, for example, if your use emacs, you should add

*~

to avoid adding emacs cache files to your git repository. A good example of a more extensive Python gitignore file can be found here on Github.

Now, you’re ready to initialize git. Enter the following in your terminal:

$ cd /path/to/myproject
$ git init
$ git add .
$ git commit -m “initial commit”

Part 3: Set Up Git (EC2)

The goal of creating a git repository on a server is to maintain a stable release that members of a group can then pull, make their own changes, and then push back to the server for deployment. If anything goes wrong, you can very easily revert to the last stable version with git.

Note: A quick note before you ssh into your EC2 server: If your .pem key is an irregular directory, run the following command on your local computer terminal:

$ ssh-add /path/to/your/certkey.pem

Now, you should be able to ssh into your server with the following command:

$ ssh ubuntu@my_ec2_ip_address

Next, create a bare git repository:

$ mkdir /home/ubuntu/myproject.git
$ cd /home/ubuntu/myproject.git
$ git init –bare
$ exit

Part 4: Set Up Git Hooks (optional)

This step is optional (depending on what exactly you’re using the server for and whether you want new versions to be automatically deployed or are using it just for storage/backup purposes–in general you’ll want to do this–if this is your only server or your first time doing this, I would recommend you do it).

Git hooks allow you to perform custom-defined function that are triggered by different git-related events. In this case, we will be using git hooks to checkout the project each time the remote repository receives a push.

$ ssh-add /path/to/your/certkey.pem
$ cd /home/ubuntu/myproject.git/hooks

Now, using your editor of choice, create a file called post-receive in the hooks folder with the following contents:

#!/bin/sh
echo “post-receive mysite.com server triggered”
GIT_WORK_TREE=/path/to/deployment/folder git checkout -f

Your deployment folder should be whichever directory you direct webserver (i.e. apache). Go ahead and save the file and exit out of ssh in your terminal.

Part 5: Set Up Git Remote (Local)

We’re almost finished! Now back on your local terminal enter the following:

$ cd /path/to/myproject
$ git remote add origin ubuntu@my_ec2_ip_address:myproject.git

This command adds the git repository on your ec2 instance as a remote “origin.” You can add any number of remote repositories with different names. For example, if you used one repository for main deployment and one for testing, you would do:

$ git remote add origin ubuntu@main_ec2_instance:main_repository.git
$ git remote add testserver ubuntu@other_ec2_instance:test_repository.git

Now, you’re ready to go ahead and push your repository from your local computer to your server:

$ git push origin master

Depending on the size of your repository, it may or may not take a while. After the push is complete, you should receive the following message (along with many others):

remote: post-receive mysite.com server triggered

This means that the push is complete and the custom git hook we wrote earlier has been activated. Now, any of your team members can easily clone the repository to their local computer:

$ git clone ubuntu@my_ec2_ip_address:myproject.git
$ cd myproject

Now you can easily clone from your EC2 server and push changes to it when necessary.

Enjoy!