As a Python and Django kind of guy, I had always been jealous of the Ruby on Rails folks. This has nothing at all to do with the framework itself. No, no, no.... Django all the way. It was the Heroku cloud application platform that had me longing.
Yes, I could run my Django application on Google App Engine, but that requires all sorts of hackery and my app ended up an abomination of the original... too unnatural for my tastes.
I sensed a small shift in the Earth's rotation on Sept 28, 2011. This is when Heroku added support for Python/Django on their platform. I needed to give it a test drive and I was amazed how simple it was. The following is an account of what I did to port one of my existing Django sites to Heroku...
Initial setup
Heroku already provides a decent quick start guide for Python. That's a great place to begin. Check out the Prerequisites and Local Workstation Setup which will get you up and running quickly. It helps if you're already familiar with Git, virtualenv and pip. If you're not, then now is an excellent time to learn!
First things first. Assuming your Django project is already in Git, change directory to the project root. Then...
$ heroku auth:login
... output omitted ...
$ heroku create --stack cedar
... output omitted ...
Believe it or not, we're almost there!
Database config
Now, my existing app is running a MySQL database. I'm going to use the built-in Postgres DB on Heroku. So I need to update my Django settings...
# Database config
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
}
}
Note, that I didn't supply any database info or credentials. Heroku auromatically injects this info into your settings.py file. I also need to dump out my current database which I can later import into my new app (this could also be done with fixtures).
$ python myapp/manage.py dumpdata > db.sql
I'm already storing my Python dependencies in a requirements.txt file. If you're not, you'll need to create this file at the project root.
$ pip freeze > requirements.txt
$ cat requirements.txt
Django==1.3
feedparser==5.1
gunicorn==0.12.2
lxml==2.3.3
psycopg2==2.4.2
python-dateutil==1.5
python-sunlightapi==1.1.0
Don't forget to commit your changes! Then push to Heroku.
$ git commit -a -m 'Mods to run on Heroku.'
$ git push heroku master
That second line above is really something to be admired. Not only does it push the code to Heroku's repository, but then it triggers a real deployment. Heroku automatically copies the files to the stack, installs all the dependencies (via requirements.txt), detects that this is a Django application, and runs the application with "runserver". Poof! Done.
Well, not quite done. But really that's bulk of the it and my app is in fact running. You can confirm this by using the "heroku ps" command.
Running your app
Now I need to do all the normal Django setup stuff, like syncdb and loaddata...
$ heroku run python myapp/manage.py syncdb
$ heroku run python myapp/manage.py loaddata < db.sql
If all goes well, I should be able to hit my site with a web browser at the wacky hostname provided by Heroku when I created the stack. Herou provides a shortcut...
$ heroku open
Final thoughts
We'll that was pretty darn easy. A few other things to note if you're trying this yourself.
- You'll need to serve static media from somewhere. I used django.contrib.staticfiles in this example, but that's probably not idea for production. Though the output does get cached... so it's also not too bad.
- You don't want to use the built-in Django runserver. I prefer gunicorn and it's easy to configure that!
- Enjoy yourself. This is cool stuff!