Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails How to upload precompiled assets to Cloudfront

  • I'm using a Rails 3.2 app
  • I created a Cloudfront distribution with a S3 origin
  • I already change config.action_controller.asset_host to my cloudfront asset
  • I'm using capistrano

I want to know, how to upload my precompiled assets to Cloudfront every time I deploy

like image 956
eveevans Avatar asked May 24 '12 22:05

eveevans


People also ask

Can you upload to CloudFront?

There is no such concept as uploading files "to" Cloudfront.

What does rake assets Precompile do?

rake assets:precompile. We use rake assets:precompile to precompile our assets before pushing code to production. This command precompiles assets and places them under the public/assets directory in our Rails application.

Can I precompile assets locally before deployment?

For instance, you may have limited write access to your production filesystem, or you may plan to deploy frequently without making any changes to your assets. In such cases, you can precompile assets locally — that is, add a finalized set of compiled, production-ready assets to your source code repository before pushing to production.

How does Sass-rails generate a CSS file?

The example used before was a controller called "projects", which generated an app/assets/stylesheets/projects.scss file. In development mode, or if the asset pipeline is disabled, when this file is requested it is processed by the processor provided by the sass-rails gem and then sent back to the browser as CSS.

How are rails assets served to the server?

By default Rails assumes assets have been precompiled and will be served as static assets by your web server. During the precompilation phase an SHA256 is generated from the contents of the compiled files, and inserted into the filenames as they are written to disk.

Should I use a CDN for Rails development?

When the CDN can serve an asset directly the request never touches your Rails server. Since the assets from a CDN are geographically closer to the browser, the request is faster, and since your server doesn't need to spend time serving assets, it can focus on serving application code as fast as possible.


3 Answers

There is no need for the s3 bucket as Amazon Cloudfront now supports "custom origins". It used to be that you had to specify a s3 bucket as the origin, but now you can point your cloudfront distribution at your rails app.

http://aws.typepad.com/aws/2010/11/amazon-cloudfront-support-for-custom-origins.html

So, after you create a distribution that is pointed at your publicly accessible app, you set your asset host in the appropriate config file e.g. production.rb and you are off to the races.

config.action_controller.asset_host = "url of your cloudfront distribution"

Here is a half decent article on how to configure things:

http://ryantownsend.co.uk/post/13126016608/cloudfront-cdn-on-rails

Don't be confused with the bit about setting up CNAME recprds for an origin subdomain. This is only relevant if you want to use your own subdomain instead of amazons.

like image 95
James P McGrath Avatar answered Oct 04 '22 01:10

James P McGrath


After installing the aws-s3 gem, you can add this at this end of your capistrano recipe :

set :cdn_user, "KEY ID" # This is called "CDN KEY API" for AWS
set :cdn_api_key, "YOUR KEY SECRET"
set :cdn_container, "bucket name"

namespace :assets do
    task :to_cdn do
      require 'aws/s3'
      AWS::S3::Base.establish_connection!(:access_key_id => cdn_user, :secret_access_key => cdn_api_key )
      assets_dir = "#{shared_path}/assets"
      Dir.glob(assets_dir + "/**/*").each do |file|
        if !File.directory?(file)
          cdn_filename = file.gsub(assets_dir,"assets")
          AWS::S3::S3Object.store(cdn_filename, open(file) , cdn_container)
        end
      end
    end
end

Using a trigger like this :

after "deploy:assets:precompile", "assets:to_cdn"

You will also need to launch the compilation at some point in your recipe with :

load 'deploy/assets'

Result : at the end of your asset compilation, all your assets are going to be pushed on S3, and you will be able to access them from cloudfront.

You then have to update your config/environment/production.rb to point to your CDN URL.

config.action_controller.asset_host = "http://assets.example.com"
like image 32
Julien Pellet Avatar answered Oct 04 '22 01:10

Julien Pellet


There's a great Ruby gem that handles this called AssetSync. If you combine it with turbo-sprockets, you can make sure that only new or updated assets are copied on deploy.

like image 39
KurtPreston Avatar answered Oct 04 '22 01:10

KurtPreston