I hope every one is aware of Amazon’s S3 service and using this service for Static contents like JS/CSS/Images. It’s a wonderful storage server with high-performance and reliability at fairly low price.I am using this service for my project and main challenge was to automate the process of uploading the static contents on the S3.
I wanted to speed up the mobile website so I decided to do following:
- Minify the CSS and JS files
- Gzip Compression of minified files
- Uploading the Static Contents on Amazon S3
I wanted to use Capistrano script to automate the process but found no straight forward solution. So I decided that I build the solution and Share it with you guys :).
Pre-Requisites:
Following are the list of plugins required on your host machine
- Capistrano 2.0.0 or greater
- YUI Compressor 2.4.2 or greater (For this you need java)
- AWS-S3 Gem
- Capistrano plugin extension S3 Asset Host Syncher
- gzip
Installation
First we need to set up Capistrano for our project and generate a capFile for the deployment. We also need to install supporting gems and libraries. Type following from the Root of your project:
gt; sudo gem install capistrano
gt; sudo gem install aws-s3
gt; ruby script/plugin install git://github.com/spatten/synch_s3_asset_host.git (Make sure its installed in /vendor/plugins/synch_s3_asset_host otherwise download the plugin from site).
gt; wget http://yuilibrary.com/downloads/download.php?file=2a526a9aedfe2affceed1e1c3f9c0579 (Extract the yuicompressor-xxx.jar and put it in /vendor/plugins/yuicompressor directory).
Capistrano configurationIn RAILS_ROOT/config/deploy.rb
Specify one of your web hosts as an “asset_host_syncher”. If you only have one web host, you don’t make a new line for this,
just edit the existing line that sets your :web role
role :web, webserver1, :asset_host_syncher => trueCreate a new task minify in the cap file:
task :minify do compressor = "java -jar #{current_path}/vendor/plugins/yuocompressor/yuicompressor-2.4.2.jar" #name of the javascript files to be minify and compressed js_list = ["xxxx","yyyyy"] javascript_path = #{current_path}/public/javascripts run "cd #{javascript_path}" js_list.each do |js| run "#{compressor} --type js #{js}.js -o #{js}.min.js" run "gzip -c #{js}.min.js >#{js}.min.js.gz" end #name of the style files to be minify and compressed css_list = ["xxxx","yyyy"] css_path = #{current_path}/public/stylesheets run ("cd #{css_path}") css_list.each do |css| run "#{compressor} --type css #{css}.css -o #{css}.min.css" run ("gzip -c #{css}.min.css >#{js}.min.css.gz" end deploy::s3_asset_host:synch_public endConfigure Capistrano to minify before doing the final symlink task:
before "deploy:symlink", "minify"S3 configuration
Create a file in RAILS_ROOT/config called synch_s3_asset_host.yml. Add the following to it,
and edit to suit:AWS_ACCESS_KEY_ID: ‘your access key here’
AWS_SECRET_ACCESS_KEY: ‘your secret key here’
asset_host_name: “xyz.com”
Configure Single asset hostFor a single asset host, simply add the following line to RAILS_ROOT/config/environments/production.rb:
config.action_controller.asset_host = "http://xyz.com"
Some tweaks in S3synch plugin
As you know that Amazon S3 have its own ways to use compressed css/js so we need few tweaks in the S3 Asset Host Syncher.To make it work gzip compression, I had to add following in the s3sync/s3sync.rb (Line 507)if @path.include? '.gz' headers['Content-Encoding'] = 'gzip' endNow we are ready to deploy our stuff on site and improve the performance of the site.
Deploy
gt; cap s3_asset_host:setup (No need if you have bucket already)
gt; cap deploy
We can add some more tweak like excluding directories for synching to Amazon S3 bucket and I have added that tweak in the comments of Asset Syncher. If there are better solutions, let me know. I'd love a simpler solution for this.