Sevenforge Sevenforge by Curtis Spencer home

CDN Fu, a framework for content distribution networks

Overview

CDN Fu is a fun domain specific language written in ruby for deployment of assets to content deliver networks. There are 4 pluggable steps in the chain:

  1. Preprocessing
  2. File Listing
  3. Minification
  4. Uploading

CDN Fu Diagram

There are a lot of ad hoc scripts and rake tasks out there that accomplish these steps, but the idea behind this is to put all the tips and tricks under the same roof in an extensible framework, so that many CDNs and minification strategies can be easily supported.

Installation

$ gem install --source=http://gemcutter.org cdn_fu

Rails Installation

First install the gem, then do the following

$ cd your_rails_dir
$ cdnfu --rails .
$ rake cdn:init

This will make cdn_fu.rb in config/ which you can use to configure CDN Fu.

An Example

In this example, we want to do the following: use Sass to generate our css files, minify the resulting css as well as our js files using YUI, then upload the minified css, js, and images to an S3 bucket, so they can be used on Cloudfront. It assumes you have a YUI jar file in /usr/bin, but that location is configurable.

RAILS_ROOT/config/cdn_fu.rb
CdnFu::Config.configure do
  asset_id RAILS_ASSET_ID
  verbose true

  preprocess do
    Sass::Plugin.update_stylesheets
  end

  files do 
    glob "javascripts/*.js", :minify => true, :gzip => true
    glob "stylesheets/*.css", :minify => true, :gzip => true
    glob "images/**/*.*"
  end

  minifier YuiMinifer do 
    yui_jar_path "/usr/bin/yuicompressor-2.4.2.jar"
  end

  uploader CloudfrontUploader do
    s3_bucket "mybucket"
    # these can be specified in environment variables
    s3_access_key "key" 
    s3_secret_key "mysecret"
  end
end

Next you want to ensure that your RAILS_ASSET_ID and asset_host are good to go by adding the following snippet into your production.rb

RAILS_ROOT/config/environments/production.rb
RAILS_ASSET_ID = "2"
# Enable serving of images, stylesheets, and javascripts from an asset server
config.action_controller.asset_host = "http://bucket.cloudfront.net/#{RAILS_ASSET_ID}"

The CloudfrontUploader requires an asset_id to be specified because of how Cloudfront does its versioning. It takes up to 24 hours for an asset to be invalidated, so in order to ensure serving of fresh assets, it is good to update RAILS_ASSET_ID whenever you change any of your js/css/image files.

Now run

$ rake cdn:upload

and then do a deploy (via capistrano or however you deploy), and your latest assets should be served from Cloudfront

Download

Future

Please let me know if you give this a try. Please file tickets over at github, or find me on Freenode as @jubos (sometimes lounging around #c or #ruby).

You can follow me on Twitter here.


Fork me on GitHub