Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Proper way to handle static files and templates for Django on Heroku

I'm moving over my django app to Heroku, and I was wondering what the proper way to handle static files is. Do I just push them via git to Heroku? Or should I be storing them on SW3 or something? Also, what should the STATIC_ROOT and such be?

Thanks!

like image 649
Parker Avatar asked Jul 19 '12 20:07

Parker


People also ask

Where should I put static files in Django?

Configuring static files Make sure that django.contrib.staticfiles is included in your INSTALLED_APPS . In your templates, use the static template tag to build the URL for the given relative path using the configured STATICFILES_STORAGE . Store your static files in a folder called static in your app.

Does Heroku support static files?

You should store them externally on a service like S3 - while Heroku can serve static files, it's not designed to.

How do you serve static files in Django in production?

Serving static files in production. The basic outline of putting static files into production consists of two steps: run the collectstatic command when static files change, then arrange for the collected static files directory ( STATIC_ROOT ) to be moved to the static file server and served.


1 Answers

You should store them externally on a service like S3 - while Heroku can serve static files, it's not designed to.

Here's a good primer on getting started with S3:

https://devcenter.heroku.com/articles/s3

Use django-storages http://django-storages.readthedocs.org/en/latest/index.html to collect static files to your S3 bucket and serve them accordingly.

These are the necessary settings you'll need to have for S3:

DEFAULT_FILE_STORAGE = 'storages.backends.s3boto.S3BotoStorage' STATICFILES_STORAGE = 'storages.backends.s3boto.S3BotoStorage'  AWS_ACCESS_KEY_ID = 'access-id' AWS_SECRET_ACCESS_KEY = 'secret-key' AWS_STORAGE_BUCKET_NAME = 'bucket-name' AWS_PRELOAD_METADATA = True # necessary to fix manage.py collectstatic command to only upload changed files instead of all files 

MEDIA_ROOT and STATIC_ROOT are superceded by DEFAULT_FILE_STORAGE and STATICFILES_STORAGE respectively and hence not needed. You will, however, want to set MEDIA_URL and STATIC_URL to something like

STATIC_URL = 'https://bucket-name.s3.amazonaws.com/static/' ADMIN_MEDIA_PREFIX = 'https://bucket-name.s3.amazonaws.com/static/admin/' 

If you want to store your static and media files in different subfolders, this is a great solution: https://stackoverflow.com/a/10825691/674794

You'll want to set MEDIA_URL and STATIC_URL to the respective new folders, e.g.

MEDIA_URL = 'https://bucket-name.s3.amazonaws.com/media/' STATIC_URL = 'https://bucket-name.s3.amazonaws.com/static/' 

You'll also want to manually execute manage.py collectstatic and disable Heroku's automatic collectstatic as per https://devcenter.heroku.com/articles/django-assets#disabling_collectstatic, as Heroku's collectstatic will reupload every static file to S3 every time you push even if the files haven't been modified, adding a hefty transfer and request load to S3 and slowing down your pushes.

Then just continue using {{ STATIC_URL }} in your templates like usual and you should be set!

<link href='{{ STATIC_URL }}css/styles.css' type='text/css' rel='stylesheet'> 

If you want to start off simple and choose not to immediately take that route though, you can do the quick hack in your urls configuration by following Cesar's mentioned post at Heroku - Handling static files in Django app, though there'll be a significant decrease in app performance.

like image 127
Intenex Avatar answered Sep 28 '22 14:09

Intenex