I’ve been trying to get to grips with Heroku lately. Here’s how to install
At FARM, we heavily use django-cms, but our traditional methods for deployment and hosting aren’t necessarily compatible with the principles of the 12-factor application. In particular, I wanted to explore the issues around file/upload handling (and persistence) and working with databases. So, here are the steps which I took.
At the time of writing, django-cms 3.0 is right around the corner, but I am more familiar with the 2.4 branch. I’ll update this post when 3.0 is available, if enough people contact me.
In this article, all the local commands are run on an OSX machine, but as long as you have a working
pip, the steps should be the same regardless of the platform. I used Postgres.app for my local database.
There are some basic things to setup before starting.
First, setup the application in Heroku:
Clone the repository, and make an initial commit:
$ git clone email@example.com:farm-django-cms-test.git Cloning into 'farm-django-cms-test'... Initializing repository, done. warning: You appear to have cloned an empty repository. $ cd farm-django-cms-test $ echo "farm-django-cms-test" >> README $ git add README $ git commit -m "Initial commit of a README file"
This is optional, but I wouldn’t be comfortable having just one remote, so add a new remote, and push there. We use BitBucket.
$ git remote add bitbucket firstname.lastname@example.org:wearefarm/farm-django-cms-test.git $ git push -u bitbucket --all Counting objects: 3, done. Writing objects: 100% (3/3), 234 bytes, done. Total 3 (delta 0), reused 0 (delta 0) To email@example.com:wearefarm/farm-django-cms-test.git * [new branch] master -> master Branch master set up to track remote branch master from bitbucket.
At this stage, setup a
.gitignore, add and then commit it. Mine looks like this:
venv *.pyc static
We need to install a virtualenv, and install Django, django-cms, and a couple of other packages which we will need later on.
$ virtualenv --no-site-packages venv New python executable in env/bin/python Installing setuptools, pip...done. $ source venv/bin/activate (venv)$ pip install Django==1.5.5 psycopg2 gunicorn dj-database-url django-cms==2.4.3 pillow django-storages <...> Successfully installed Django psycopg2 gunicorn dj-database-url django-cms Pillow django-storages django-classy-tags south html5lib django-mptt django-sekizai six Cleaning up...
Now we have everything we will need, freeze those requirements:
(venv)$ pip freeze > requirements.txt
Django on Heroku
I wanted to make sure that I had everything in place to run Django on Heroku at this point. So, create a Django project:
(venv)$ django-admin.py startproject example .
Then, setup a
Procfile and test it with
(venv)$ echo "web: gunicorn example.wsgi" > Procfile (venv)$ foreman start 20:50:20 web.1 | started with pid 3566 20:50:20 web.1 | 2014-03-22 20:50:20  [INFO] Starting gunicorn 18.0 20:50:20 web.1 | 2014-03-22 20:50:20  [INFO] Listening at: http://0.0.0.0:5000 (3566) 20:50:20 web.1 | 2014-03-22 20:50:20  [INFO] Using worker: sync 20:50:20 web.1 | 2014-03-22 20:50:20  [INFO] Booting worker with pid: 3569
I could then test if Django was running locally, by visiting
Let’s push this code to Heroku, and make sure we get the same results.
(venv)$ git add . (venv)$ git commit -m "Initial Django code." [master 7550808] Initial Django code. 6 files changed, 133 insertions(+) create mode 100644 Procfile create mode 100644 example/__init__.py create mode 100644 example/settings.py create mode 100644 example/urls.py create mode 100644 example/wsgi.py create mode 100755 manage.py create mode 100644 requirements.txt (venv)$ git push origin master Initializing repository, done. Counting objects: 16, done. Delta compression using up to 4 threads. Compressing objects: 100% (11/11), done. Writing objects: 100% (16/16), 2.72 KiB, done. Total 16 (delta 0), reused 0 (delta 0) -----> Python app detected -----> No runtime.txt provided; assuming python-2.7.6. -----> Preparing Python runtime (python-2.7.6) -----> Installing Setuptools (2.1) -----> Installing Pip (1.5.4) -----> Installing dependencies using Pip (1.5.4) <...> Successfully installed Django Pillow South dj-database-url django-classy-tags django-cms django-mptt django-sekizai django-storages gunicorn html5lib psycopg2 six Cleaning up... -----> Discovering process types Procfile declares types -> web -----> Compressing... done, 38.2MB -----> Launching... done, v5 http://farm-django-cms-test.herokuapp.com/ deployed to Heroku To firstname.lastname@example.org:farm-django-cms-test.git * [new branch] master -> master
You’ll notice the URL of the deployed application above (though I assume that your URL will be slightly different). At the moment, if you visit that URL, then you won’t get a response. We need to add a dyno:
(venv)$ heroku ps:scale web=1 Scaling dynos... done, now running web at 1:1X.
Now, visit the URL:
Now that we have our Django project running on Heroku, all that remains in part two is to complete the
django-cms setup, and then deal with our static media and uploads.