3

I have a django/mezzanine/django-cumulus project that uses the rackspace cloudfiles CDN for media storage. I would like to automatically serve all static files from the local MEDIA_ROOT, if they exist, and only fallback to the CDN URL if they do not.

One possible approach is to manage the fallback at the template level, using tags. I would prefer not to have to override all the admin templates (eg) just for this, however.

Is there a way to modify the handling of all media to use one storage engine first, and switch to a second on error?

evilchili
  • 73
  • 7

2 Answers2

1

The best way is to have this working, is to have a different web server serving all of your media (I used nginx). Then you setup a load balancer to detect failure and redirect all the requests to CDN in case of a failure. One thing that you might have to figure out is the image path.(use HAProxy to rewrite the request URL, if you need to)

Anup
  • 743
  • 6
  • 12
  • An interesting idea. I think the load balancer is overkill though; perhaps catching 404s and redirecting them would be sufficient. This might be done at the webserver level, or with a custom 404handler in the django app? I will have to experiment. – evilchili Feb 28 '14 at 00:18
  • Right, for moment before posting this, i thought it would be a good idea to hack core.context_processors.static. But i am really not sure if that is the right way to do it. we need to have a check before doing return {'STATIC_URL': settings.STATIC_URL}. But this is going to happen on every request, and this is definitely going to effect the app's response time, thus i felt we should not be having it there. Let us know how it goes. – Anup Feb 28 '14 at 00:34
0

Based on Anup's suggestion, I found that this bit of nginx config nicely handles the 404 condition:

location /static/ {
    root            /path/to/static_root;
    # ...
    error_page 404 =  @cdn;
}

location @cdn {
    # cdn_cname.example.com is an alias for deadbeef012345.r99.cf5.rackcdn.com
    rewrite ^/(.*)$ http://cdn_cname.example.com/$1 last;
}

This will correctly redirect any request for a /static/ URI that returns 404 on the local server to the CDN. However, django-cumulus still renders links to static files via the CDN. To fix that, I added the following to the CUMULUS block of settings.py:

CUMULUS {
    # ...
    'CONTAINER_URI': 'http://example.com/static',
}

Now, django-cumulus links use the local server's static URI, which will hit the nginx configuration above, and only redirect to the CDN when necessary. Hooray!

evilchili
  • 73
  • 7