Serving Django Static Files on Heroku (Posted on December 15th, 2012)

One of my goals when creating this blog was to create a blog that I never had to pay for. Luckily Heroku's free tier allowed me to do just that. While my blog doesn't have many static files (CSS, JS and images) Heroku typically recommends that you host them on Amazon which isn't free. However, Heroku gives you 100mb of free space for your app so I wanted to take full advantage of that and the free bandwidth they offer.

I tested a few different webservers and found Tornado to work the best after some load testing with The other ones I tested were CherryPy, FAPWS3, and Gunicorn with Tornado. After a bit of tinkering with getting Tornado to host static files here is what I came up with (go ahead and replace "burstolio" with the name of your app):

import os, sys
import django.core.handlers.wsgi
from tornado import httpserver, ioloop, wsgi, web

from optparse import OptionParser
parser = OptionParser()

parser.add_option('--port', dest='port')

options, args = parser.parse_args()
def runserver():
    app_dir = os.path.abspath(os.path.dirname(__file__))
    os.environ['DJANGO_SETTINGS_MODULE'] = 'burstolio.settings'
    wsgi_app = wsgi.WSGIContainer(django.core.handlers.wsgi.WSGIHandler())
    application = web.Application([
        (r"/static/(.*)", web.StaticFileHandler, {"path": "/app/burstolio/static"}),
        (r".*", web.FallbackHandler, dict(fallback=wsgi_app)),

    server = httpserver.HTTPServer(application)
    except KeyboardInterrupt:

if __name__ == '__main__':

The first part allows me to specify a port which Heroku will assign automatically. Getting into the runserver function we first start by adding the app to the system path so that our app can be found. After that we create a WSGI (Web Server Gateway Interface) container to hold our app in a way that we can serve to users.

The next part is the important part where the web app's URLs are setup. It's important that the static files go first otherwise Tornado will match the WSGI container regex which will 404. Make sure that your file has the STATIC_URL and STATIC_ROOT set to match the regex you specify for the StaticFileHandler. Here is an example of how I setup my Once the web app is setup the rest is as simple as creating an HTTP server and listening on the specified port.

If you're running on Heroku and want to give this a try your procfile should look something like:

web: python --port=$PORT

If you know of a better way to host static files on heroku, run into any problems or have any questions let me know in the comments!

Tags: Django, Heroku


  • Shannon -jj Behrens - 1 year, 6 months ago

    Instead of setting up StaticFileHandler explicitly, I think you can do:

    application = web.Application( static_path=settings.STATIC_ROOT, handlers=[ (r".*", web.FallbackHandler, dict(fallback=wsgi_app)), ])


  • Max Burstein - 1 year, 5 months ago

    I think you are correct. Not sure if that method was around back when I first worked on this blog. I did come across it while launching my new site and it worked exactly the same. Always good to have options :)


  • Salesforce Training in Chennai - 2 months ago

    Rename your index.html to home.html or something similar. Create an index.php file with the following code:

    <?php include_once("home.html"); ?>

    That’s it!


  • easiest way to hack top eleven - 1 month, 3 weeks ago

    Get the easiest way here to hack top eleven without paying any money.


  • bonton - 1 month, 1 week ago

    My buddy votes I can <a href="">will you write my essay for me</a> from this locale. How do I go about this being sum I can discover here is info on what to squint for in a composition or a author? Do you get a table of utilitys I can decide from?


  • Anonymous - 1 month, 1 week ago

    [url=]commercial roof cleaning Orlando[/url]


  • Puja Kumari - 1 week, 5 days ago

    Thanks for post this helpful post - Please visit for More information about:


  • Puja Kumari - 1 week, 5 days ago

    Thanks for Nice and Informative Post. This article is really contains lot more information about This Topic