Django seamless upgrades with CDN
[I'm using AWS but I think this question is relevant to all CDNs]
I'm looking to seamless deploy my Django server to the AWS cloud.
All static content (e.g. images, javascript, etc.) go to the Amazon Cloudfront CDN. The problem is that I'm trying to make the upgrade as "atomic" as possible, while I have very little control over the timing of CDN object invalidation. According to TFM, the solution is to version my objects, i.e. rename them adding a version id, e.g. arrow_v123.png. Obviously if the new server points to arrow_v124.png I have complete control over the timing of the entire distribution. I checked and from what I can tell the big boys are doing that - Facebook static content objects have a hashed name (and path).BUT HOW DO I AUTOMAGICALLY DO THIS IN DJANGO?
I need to somehow:
- Generate a new version number
- Change all the names of all the objects that are static
- Change all the templates and python code to use those new names
Or somehow integrate with the development process:
- I edit a picture or a javascript file
- I save it and it gets a new name?!?! and all references to it are auto-corrected?!?!
I'm using Fabric for deployments, so it makes sense I nee开发者_开发知识库d to modify my fabfile somehow.
Please help.
Tal.
http://www.allbuttonspressed.com/projects/django-mediagenerator provides asset versioning. It provides a function and a template tag to give you the versioned filename from the actual filename. It also has some nice extras like js/css minification and concatenation.
Have a look at html5boilerplate, has ant build scripts which as well as doing a lot of other things rename your static js/CSS references to a random number and changes any references in your template files to these new random numbered js/CSS. I don't think it does the same for image assets but I suppose the ant files could be changed to perform the same.
Django port of html5boilerplate is here: https://bitbucket.org/samkuehn/django-html5-boilerplate
Seems to me the last part (change all templates and python code to use the new names) is easy. Store the current style "version number" in your settings. Make sure this version number is passed to your templates using the template context. Then, use that when rendering the templates to select the real URL to static files.
The steps involved in publishing a new set of static files is:
- publish the new files to your CDN
- edit your settings file
- re-load your application settings
You can achieve the same type of effect using a similar scheme by storing the version number in the database rather than in the settings. This avoids the reload and changes are immediate, but will add a DB query at each view render.
How you integrate each of these steps into your development process is up to you. It might be possible to (conditionally) automate publishing to the CDN, editing the settings file and restarting the application. To "edit" the settings file easily, you can store the version number in a separate file and have the settings file read that on start-up.
I'd append a random string to the end of all the static assets you update often.
Example: style.css will become style.css?ASFDSF34343SDSFDSF
In debug mode, I ensure that the random string changes on each request, so my changes take effect right away. (this prevents browser caching)
In production, the random string is ONLY generated once on start-up and reused thereafter.
You can have it so the random string sticks around after a restart of your web server too.
This has been working very well for me, both during the development as well as in production.
Mind you that I keep my assets on S3 and have not enabled the CloudFront yet.
Here is the actual example:
http://static.outsourcefactor.com/css/main.css?ASDFASFASF434434
精彩评论