Audvik Labs

How to put Rails assets on AWS S3 and fetch using CloudFront?

I have been working on Rails projects for more than 5 year and I always wanted to serve the assets (images | js | css) files at the best speed so that page load time is minimum. In order to do that I came across a lot of gems and services but for me the best gem to was fog-aws and the best service was that of AWS CloudFront.

Why S3 and CloudFront?

S3 is the mostly used service of Amazon Web Services(AWS). As S3 is objects storage so it is one of the best place to store videos, images, javascript files and stylesheets. The high availability of S3 and CORS Configuration are the salient features of S3 which helps us host our Rails Assets in a sublime way. It grants user permission to make the objects public (accessible to all) or private (accessible to authorized users) for our case as we are using it to serve assets using S3 so we need to make bucket publicly readable. However we have been using S3 to serve contents in both public mode and private mode ( this is for the users who upload some contents on our app).

One of the issues with S3 is that its hosted in a region (i.e. at a specific Geo Location) but our customers can access our app from any part of the word and in order to provide best speed we need to have a solution | service which could serve the assets at the best speed throughout the globe. In order to achieve this we can use CloudFront i.e. another exalted service by AWS.

CloudFront is global content delivery network (CDN) service that securely delivers data, videos, applications, and APIs to your viewers with low latency and high transfer speeds. As per AWS The Amazon CloudFront content delivery network is built on the expanding global AWS infrastructure that currently includes 54 Availability Zones within 18 geographic regions today. Amazon plans to add 12 more Availability Zones and 4 more Regions in Bahrein, Hong Kong SAR, and Sweden, as well as a second AWS GovCloud Region in the United States. Amazon CloudFront has 116 Points of Presence (105 Edge Locations and 11 Regional Edge Caches) in 56 cities across 24 countries. Our network of Edge location helps ensure that your applications deliver high availability, scalability, and performance for all of your customers from anywhere in the world.

(Reference: https://aws.amazon.com/cloudfront/)

Apart from these another reason to use these services is their cost.

Now as you are familiar with the advantages of S3 and CloudFront so lets give it a shot. You can follow followings steps in order to build this architecture.

Step 1

Modify your Gemfile. Add the fog-aws and asset_sync gem to your gemfile.

gem “fog-aws”
gem “asset_sync”

Step 2

Create S3 Bucket in the region where you have hosted your app server and grant public read access to it. You can update your S3 CORS Configuration to access the assets from your website.

CORS Configuration
CORS Configuration

<?xml version=”1.0″ encoding=”UTF-8″?>
<CORSConfiguration xmlns=”
http://s3.amazonaws.com/doc/2006-03-01/“>
<CORSRule>
<AllowedOrigin>
https://yourwebapp.com</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<MaxAgeSeconds>3000</MaxAgeSeconds>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>

Step 3

Create IAM User with permission to create and update S3 bucket or you can give Full Access.

Step 4

Create CloudFront Distribution

You can use search to look for any AWS service that you wish to use.
You can use search to look for any AWS service that you wish to use.
Select the Web Distribution
Select the Web Distribution
In Origin Domain Name write your S3 bucket name and it will show in suggestion. Rest options you can leave as default.
In Origin Domain Name write your S3 bucket name and it will show in suggestion. Rest options you can leave as default.
Copy the Domain Name. This is the url through which we will access the Assets.
Copy the Domain Name. This is the url through which we will access the Assets.

Step 5

Add an initialize file or put the following code in production.rb after the configure block.

AssetSync.configure do |config|
config.fog_provider = ‘AWS’
config.aws_access_key_id = ENV.fetch(‘AWS_ACCESS_KEY_ID_IAM’)
config.aws_secret_access_key = ENV.fetch(‘AWS_SECRET_ACCESS_KEY_IAM’)
config.fog_directory = ENV.fetch(‘ASSET_S3_BUCKET’)
config.fog_region = ENV.fetch(‘AWS_S3_REGION’)
end

Update your production.rb file.

config.action_controller.asset_host = ENV.fetch(‘AWS_CLOUD_FRONT_URL’)
config.action_mailer.asset_host = ENV.fetch(‘AWS_CLOUD_FRONT_URL’)

config.serve_static_files = true
config.assets.compile = true
config.assets.digest = true
config.assets.enabled = true
config.assets.initialize_on_precompile = true

Congrats your have configured your Rails App to compile and put Assets to S3 and fetch using CloudFront.

Leave a comment

Your email address will not be published. Required fields are marked *