How to set up AWS Cloudfront to serve Assets for Rails App

If you are wondering “why use a CDN to serve assets in the first place?”, then this article is not for you. However, if you have already decided you want to use cloudfront, then I hope you will find this helpful.

There are a lot of good write ups out there already on how to go about doing this. One good example is from Happy Bear Software.

However there are a few additional gotcha’s that you might run into. I’ll attempt to summarize all the necessary steps here.

Getting your rails App to serve assets

First step is to have a rails app that is serving your assets. You can do so by setting serve_static_assets = true on production, which in turns adds the middleware ActionDispatch::Static or alternately by using Rack::Static.

Next, if your app will be also serving fonts make sure to provide CORS support. An easy way to do this is to use rack/cors middleware making sure that it is before Rack::Static on your middleware stack.

e.g. first thing on your

require 'rack/cors'
use Rack::Cors do
allow do
origins '*'
resource '/assets/*', :headers => :any, :methods => [:get]

Create a AWS cloudfront distribution

Create a new cloudfront distribution making sure that you point the origin domain to your domain.

And for CORS, make sure to whitelist the origin header, like so:

After your distribution is done provisioning, test that things are working by loading (look at your manifesto or some file from public/assets). Check that headers are correctly set for origin and max-age, etc. Hint: use your fav tool here e.g. Dev Console in Chrome

Have your App point to the new cloudfront distribution

Change your production.rb config to point assets to

config.action_controller.asset_host = "https://#{ENV['YOUR_CLOUDFRONT_CDN_DOMAIN']}"

and do the same for action mailer.

You dont have to use an Env variable here, but I found it useful that you can change domains without having to deploy new code.

Another tip is that you might want to add the link to a dns prefetch on your page head to speed up page loads.