Minify, Compress and Synch your assets on Amazon S3 using Capistrano and Rails

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

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:

$> sudo gem install capistrano
$> sudo gem install aws-s3
$> 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).
$> wget http://yuilibrary.com/downloads/download.php?file=2a526a9aedfe2affceed1e1c3f9c0579 (Extract the yuicompressor-xxx.jar and put it in /vendor/plugins/yuicompressor directory).

Capistrano configuration

In 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 => true

Create 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
end

Configure 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 host

For 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'
end

Now we are ready to deploy our stuff on site and improve the performance of the site.

Deploy

$> cap s3_asset_host:setup (No need if you have bucket already)
$> 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.

Minify, Compress and Synch your assets on Amazon S3 using Capistrano and Rails was last modified: April 11th, 2016 by Kapil Jain