the future is in beta

home about

Deploy django-CMS to Heroku and Amazon S3

06 May 2013

Although I’m a Ruby on Rails lover today I’m going to write about how to deploy a fresh installation of django-CMS to Heroku using Amazon S3 for storing static files.

This is a compilation from these sites:

First of all we’ll create our application directory my_app

$ mkdir my_app && cd my_app

Next, we’ll create our Python’s virtual environment using virtualenv and activate it

$ virtualenv --no-site-packages venv 
$ source venv/bin/activate

Now we can install required Python packages like django itself, django-cms, gunicorn (web server) and some others with pip

$ pip install Django psycopg2 gunicorn dj-database-url django-cms PIL django-storage

We’ll need the requirements.txt file to deploy to Heroku

$ pip freeze > requirements.txt

And create our django project inside the current directory:

$ startproject my_app .

Add these lines to the my_app/ file

# -*- coding: utf-8 -*-
import os
gettext = lambda s: s
PROJECT_PATH = os.path.abspath(os.path.dirname(__file__))

and add these in your INSTALLED_APPS array inside my_app/

	# ...

And add these to your MIDDLEWARE_CLASSES and TEMPLATE_CONTEXT_PROCESSORS arrays inside my_app/


Now we’ll configure our templates. First, create the directory where we’ll put our django templates

$ mkdir templates

and create two empty files:

$ touch templates/template_1.html
$ touch templates/template_2.html

in order two access these templates we have to put them in our file and set up available languages

    # The docs say it should be absolute path: PROJECT_PATH is precisely one.
    # Life is wonderful!
    os.path.join(PROJECT_PATH, "templates"),

    ('template_1.html', 'Template One'),
    ('template_2.html', 'Template Two'),
    ('en', 'English'),

Now let’s configure our my_app/ First, uncomment this line


And add these lines

urlpatterns = i18n_patterns('',
    url(r'^admin/', include(,
    url(r'^', include('cms.urls')),

if settings.DEBUG:
    urlpatterns = patterns('',
    url(r'^media/(?P<path>.*)$', 'django.views.static.serve',
        {'document_root': settings.MEDIA_ROOT, 'show_indexes': True}),
    url(r'', include('django.contrib.staticfiles.urls')),
) + urlpatterns

Now let’s create the base layout inside templates directory templates/base.html

{% load cms_tags sekizai_tags %}
      {% render_block "css" %}
      {% cms_toolbar %}
      {% placeholder base_content %}
      {% block base_content %}{\% endblock %}
      {% render_block "js" %}

And we can edit the templates/template_1.html template

{% extends "base.html" %}
{% load cms_tags %}

{% block base_content %}
  {% placeholder template_1_content %}
{% endblock %}

If you just did a fresh install of django projects run these commands to set up your database

$ python syncdb --all
$ python migrate --fake

If you want to fire up a webserver to test your local set up you can run

$ python runserver

Now you can open a browser window and go to http://localhost:8000/

In order to deploy to Heroku we’ll have to setup the database in the my_app/

# Parse database configuration from $DATABASE_URL
import dj_database_url
DATABASES['default'] =  dj_database_url.config()

# Honor the 'X-Forwarded-Proto' header for request.is_secure()

Add a Procfile file in your project root

web: gunicorn my_app.wsgi: 

Finally add your Amazon credentials into

# Amazon S3 credentials
AWS_ACCESS_KEY_ID       = os.environ['AWS_ACCESS_KEY_ID']

# Amazon S3 URL
AWS_STORAGE_BUCKET_NAME = '<your-bucket-name>'

# Static files location
STATICFILES_STORAGE = 'storages.backends.s3boto.S3BotoStorage'

# Default File storage
DEFAULT_FILE_STORAGE = 'storages.backends.s3boto.S3BotoStorage'

If you need to use Amazon S3 using http instead of https change this constant to False


You may alse collect your static files and upload them to Amazon S3

$ python collectstatic

Now you can push to Heroku and set up the database

$ git push heroku master
$ heroku run python syncdb --all
$ heroku run python migrate --fake

After adding a new plugin or changing your database you’ll have to execute

$ heroku run python syncdb
$ heroku run python migrate