Django static files... catching the unicorn
Anyone who has worked with Django understand the headache that is static files. While the built-in staticfiles
package is great, it does not play nicely with CDNs such as Amazon's S3. After very little digging, one can find django-storages
, but the documentation is severely lacking. Hopefully this helps.
Note: I am assuming you are already operating in a virtual environment.
Steps
If you follow these six steps, you will be serving static files like a pro!
Step 1
Download django-storages
:
$ pip install django-storages boto
Step 2
Add storages
to your installed apps in settings.py
.
INSTALLED_APPS = (
...
'storages',
...
)
Step 3
Get your AWS Security Credentials. You will need the ACCESS_KEY_ID
and the SECRET_ACCESS_KEY
. Save these for Step 4.
Step 4
Add the following variables to your settings.py
:
AWS_ACCESS_KEY_ID = 'your-access-key-id-from-step-3'
AWS_SECRET_ACCESS_KEY = 'your-secret-access-key-from-step-3'
SITE_ROOT = os.path.dirname(os.path.realpath(__file__))
And modify the following variables in your settings.py
:
STATIC_ROOT = os.path.join(SITE_ROOT, 'local_static')
STATICFILES_DIRS = (
os.path.join(SITE_ROOT, 'static'), # Assuming your static files are in a folder named ``static``
)
Make sure you have a directory named local_static
and static
and that you have imported os
.
Step 5
Add the following in your production settings. If you don't have separate settings for development and production, see my pro tip on the subject.
In settings.py
:
if os.environ.get('PRODUCTION', False):
AWS_STORAGE_BUCKET_NAME = 'static.mydomain.com'
DEFAULT_FILES_STORAGE = 'storages.backends.s3boto.S3BotoStorage'
STATICFILES_STORAGE = DEFAULT_FILES_STORAGE
AWS_S3_CUSTOM_DOMAIN = AWS_STORAGE_BUCKET_NAME
The AWS_S3_CUSTOM_DOMAIN
setting is optional. If you name your S3 bucket static.mydomain.com
, you can create a CNAME to static.mydomain.com
that is an alias for static.mydomain.com.s3.amazonaws.com
. Then, you can serve your production-ready static files from your own domain!
Step 6
Add the static files URL patterns.
In urls.py
:
from django.conf.urls import patterns, url
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
urlpatterns = patterns('',
... # Your patterns
)
urlpatterns += staticfiles_urlpatterns()
Summary
So what did we do? We implemented a method so that we can use to serve static files from the development server locally and from the production server using Amazon S3. This is great because we have quick access to our static files, e.g., *.html, *.css, *.js, while developing; but we can serve them from a CDN to reduce costs and improve performance.
Furthermore, we can send any files uploaded by users directly to the CDN, which is a critical need when using certain PaaS's such as Heroku.