Asset ID β Asset stamping and uploading to S3 for Rails
About
Uploads static assets to Amazon S3 with unique identifiers encoded into the path of the asset.
Only works with Rails 3.x because Rails 3 makes doing this sort of thing a lot easier and
that is all I needed it for.
This library takes standard Rails asset paths such as /stylesheets/main.css?1288717704
and converts them
into http://my_bucket.s3.amazonaws.com/stylesheets/main-id-95df8d9bf5237ad08df3115ee74dcb10.css
.
It uses an MD5 hash of the file contents to produce the id so the same asset will always have the same ID.
In my quest to achieve a Google Page Speed score of 100, this library achieves the following:
- Assets served from a cookie-less domain
- Unique identifier is not encoded into a query parameter (so it is cacheable by proxy servers)
- All assets have far-future expires headers for caching
- Assets have the Cache-Control: public header for caching
- CSS and javascript is GZipped and the correct headers are added
As an added bonus, all your assets are available over https://
as well.
Usage
Add the gem to your Gemfile
gem "asset_id"
Configure config/environments/production.rb
to use Amazon S3 as the asset host
and to use the id-stamped asset paths in helpers
config.action_controller.asset_host = Proc.new do |source|
'http://my_bucket.s3.amazonaws.com'
end
config.action_controller.asset_path = Proc.new do |source|
AssetID::Asset.fingerprint(source)
end
Add your Amazon S3 configuration details to config/asset_id.yml
production:
access_key_id: 'MY_ACCESS_KEY'
secret_access_key: 'MY_ACCESS_SECRET'
bucket: "my_live_bucket"
Optionally create a rake task in lib/tasks/asset_id_tasks.rake
to
perform the upload for use in your deploy scripts
namespace :asset do
namespace :id do
desc "uploads the current assets to s3 with stamped ids"
task :upload do
AWS::S3::DEFAULT_HOST.replace "s3-eu-west-1.amazonaws.com" # If using EU bucket
AssetID::Asset.asset_paths += ['favicon.png'] # Configure additional asset paths
AssetID::S3.upload
end
end
end
SSL configuration
If you want to use the SSL host in your configuration you can do so in config/environments/production.rb
config.action_controller.asset_host = Proc.new do |source|
request.ssl? 'https://my_bucket.s3.amazonaws.com' : 'http://my_bucket.s3.amazonaws.com'
end
CSS Images
By default any relative CSS images that match files on the filesystem are converted to AssetID paths as well.
For S3, if you donβt specify a prefix
it will use the http://
bucket URL by default. You can override this in config/asset_id.yml
. For example if you wanted to use the https://
url:
production:
access_key_id: 'MY_ACCESS_KEY'
secret_access_key: 'MY_ACCESS_SECRET'
bucket: "my_live_bucket"
prefix: "https://my_bucket.s3.amazonaws.com"
CDN)
Using Amazon CloudFront Content Delivery Network (To use Amazon CloudFront as a CDN for your assets all you need to do is create a CloudFront distribution for the bucket you have defined your configuration and then substitute your unique CloudFront domain name in config/environments/production.rb
config.action_controller.asset_host = Proc.new do |source|
'http://my_domain.d374pjuyllr15e.cloudfront.net'
end
SSL works fine here as well.