Just a tip for those experimenting with gzip in nginx, if you haven't, have a look into gzip_static:
http://wiki.nginx.org/NginxHttpGzipStaticModule
Just like it sounds, stash a copy of static files pre-gz'd, to save repeated compression overhead.
For "expires: max", this one's obvious in retrospect but I needed it pointed out...
If you're using svn or git or whatever, a proper vcs for your files? You have the perfect source of data for file versioning right there! In your deploy script just tweak a couple of steps:
Code:
# Pre-checkout, remove the files
rm /var/www/domain/static/*_.css
rm /var/www/domain/static/*_.js
# Checkout from vcs
svn update /wherever/domain/
# Post-checkout grab the file version
version = svn get version of file
# Then append to filename... keep it for later, too!
# I use an ugly, unique "hook" just in case
# eg. *.js -> *---version_.js)
mv filename.js filename---$version_.js
# ( I really can't remember the commands for much of this off
# the top of my head though, sorry, will edit this later when I
# have a minute to dig up the config files )
# And update your templates/html/whatever:
# (eg. Replace a hook, similar to above:
# <link rel="stylesheet" href="static.domain.com/css/base==VERSION==.css" />
# you can grep your templates dir to get "htmlfiles"...
# then iterate them dropping in the version, etc. )
htmlfiles = grep "==VERSION==" /sitedir/templates/*.html
for staticname in staticnames:
for htmlfile in ( /sitedir/templates/*.html )
sed 's/filename==VERSION==/filename$VERSION' $f > $tempfile
mv $tempfile $htmlfile
# OR symbolic link, but I've never had a use case for it, perhaps
# useful if you can't use rewrites or you want to avoid the regex
#
# ln -s /staticdir/css/cssname.css /staticdir/css/cssname---version_.css
Then add a "rewrite static.dn.com/(js|css)/(.*)---(.*)_\.(js|css) static.dn.com/$0/$1.$3" rule in your web server of choice, and you never need worry about stale files again!
As above, if you can't use rewrites or have other reasons you could use a symbolic link or equivalent, of course. Just make sure your web server is ok with following them.
Gotchas:
- Don't make the "hook" in the filename so ugly your server or older browsers could have an issue with it! (Sounds silly but can happen)
- Make sure to delete the files prior to the checkout from vcs... and that this is strictly a production, deploy, one-way thing, no changes being written back to the repo. This is the scrappy bit, but it worked for us on 10+ front-end servers for 2 years, it's good enough.
- Try to do minification / automated code shrinking, etc. as a step after the checkout, on the static server itself, if you can... Helps avoid minor differences causing full updates to all of your users.
[ Edit: Updated to explain the href/template situation, thanks db3l!
I've abandoned any and all attempts of making pseudocode remotely runnable, will replace it with real Python if I can find the script later... ]