Deploying Django 1.4 to Heroku

Note: It is assumed that your are keeping track of your changes using Git. If you aren’t, you’ll need to be to deploy to Heroku.

If there is one thing that scares beginners away from Django, its the idea of deployment. For a PHP programmer, deployment can be as simple as FTP’ing some files to a server, and boom, deployed. This isn’t to say that PHP deployment is simple. If you have to do it from scratch (get apache running, get your db installed, get PHP installed and configured, etc, etc) it can still be very complex, but many hosting companies take care of this for you. It’s almost like you never even have to think about it, which isn’t always the case for Django. That doesn’t mean its a bad thing, just…different.

So where do we start? Heroku is as good a place as any.

Heroku


Heroku is a cloud service for easy deployment of web applications. Initially it was Ruby only, but has been working hard to become a deployment service for many languages including Java, Python, and Node.js. Deploying to Heroku assumes a few things:

  1. You are familiar with Git and use it to track your code changes.
  2. You are at least passingly familiar with PostgreSQL, because that’s what you will being using. (You can use other storage devices, but PostgreSQL is the default and easiest to setup.
  3. You use PIP to manage your project’s requirements. If you aren’t doing this, you need to be. (seriously, it’s worth the effort)

Now that we have that out of the way, let’s get started. Before we can proceed further, you’ll need to get a Heroku account set up. For our testing purposes, a free account should be plenty.

  1. Go to Heroku.com and set up an account.
  2. Go to https://toolbelt.herokuapp.com and download the Herok toolbelt. Follow the directions on this page up to the “login” section.

That’s all for setting up Heroku for now. Next, we’re going to move on to configure Django so it can be deployed.

Django

Django gives you the flexibility to use almost any database under the sun. I generally develop using MySQL, but Heroku uses Postgres. As long as you haven’t been hand-tailoring queries, this shouldn’t provide any problem whatsoever. To make your project compatible with Heroku, you need to install the psycopg2 library.

pip install psycopg2

Now that you have the Postgres library installed, when your app is pushed to Heroku, Heroku will append some code to the end of your settings.py file that will point your install to the correct database.

Speaking of settings.py, you’ll also need to get your template and media paths set up correctly. To do that, add the following to the top of your settings.py and then set your paths to look like this:

import os.path
root = os.path.dirname(__file__).replace('\\','/')
 
MEDIA_ROOT = root + '/../media/'
STATIC_ROOT = root + '/../static/'
TEMPLATE_DIRS = (
    root +'/../templates',
)

We use this calculate root variable because it’s kind of a pain to know the path of your install on Heroku. This way it doesn’t matter where you deploy your app to, it should just work. Another thing to consider is static files. Heroku can be made to serve them, but having the same domain that is serving your site serve your static files is bad practice.

Wrapping it up

Now that Django is configured for Heroku deployment, all that’s left is to deploy it! The first thing we need to do is create a requirements file so that Heroku knows what packages to install. At the top level of your project, run the following:

pip freeze > requirements.txt

Great, now if you look at the generated file you can see what software Heroku is going to install for you. Next up, we’re going to create an app on Heroku (assuming you set up the Heroku tool belt correctly). In the top level directory of your project, run the following.

heroku create --stack cedar

This added your new Heroku app as a remote on your local Git repository. All you do to deploy is:

git push heroku master

Which should give you some output that looks like:

Counting objects: 10, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (8/8), done.
Writing objects: 100% (10/10), 3.59 KiB, done.
Total 10 (delta 0), reused 0 (delta 0)

-----> Heroku receiving push
-----> Python/Django app detected
-----> Preparing Python interpreter (2.7.2)
-----> Creating Virtualenv version 1.7
       New python executable in .heroku/venv/bin/python2.7
       Also creating executable in .heroku/venv/bin/python
       Installing distribute........done.
       Installing pip...............done.
       Running virtualenv with interpreter /usr/local/bin/python2.7
-----> Activating virtualenv
-----> Installing dependencies using Pip version 1.0.2
       Downloading/unpacking Django==1.4 (from -r requirements.txt (line 1))
       ...
       Successfully installed Django psycopg2
       Cleaning up...
-----> Injecting Django settings...
       Injecting code into ./hellodjango/settings.py to read from DATABASE_URL
-----> Discovering process types
       Procfile declares types         -> (none)
       Default types for Python/Django -> web
-----> Compiled slug size is 9.3MB
-----> Launching... done, v4
       http://simple-spring-9999.herokuapp.com deployed to Heroku

To git@heroku.com:afternoon-sword-29.git
* [new branch]      master -> master

On the line immediately after “—–> Launching… done,…”, the url of your project is displayed. Before you go to it though, you need to run syncdb on Heroku. The Heroku toolbelt makes this pretty easy:

heroku run python manage.py syncdb

Conclusion

That’s all there is to it. If you get stuck, feel free to leave a comment. Heroku also has a great guide for getting up and running and explains some more features of the Heroku tool belt. That can be found here.

3 thoughts on “Deploying Django 1.4 to Heroku

  1. Dwight Gunning

    Nice write up. It’s definitely an option for basic CRUD sites but check your architecture and dependencies if you’re planning anything out of the ordinary.

    I got stuck on postgres GIS support (not ready to pay for a dedicated DB), and lack of system libraries (PIL, OpenGL etc.).

    Reply
    1. Jack Slingerland

      Agreed. I wouldn’t use it for complicated sites, but it works great for simple ones that don’t require a lot of special libraries and packages. Do other Django cloud options have similar restrictions?

      Reply
    2. huxley

      If you really need PostGIS, you can always just run your database on Amazon’s EC2 east-1c since that is the colo where Heroku is based in. The database settings just need to be set as environment variables.

      For libraries, I haven’t had any trouble installing anything including PIL but if there is an issue you can fork the Python buildpack https://github.com/heroku/heroku-buildpack-python and install anything you need through that.

      Neat stuff is being done with buildpacks, Mike Tigas built a Pypi build pack: https://github.com/mtigas/heroku-buildpack-pypy

      Others have buildpacks that let you install stuff like npm modules: https://github.com/r4vi/heroku-buildpack-django

      Reply

Leave a Reply

Your email address will not be published. Required fields are marked *


five + 3 =

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>