Problems serving .js and .css assets cloudfront CDN Heroku Rails 4 App - ruby-on-rails

I am trying to host the assets of my Rails 4 App over Cloudfront CDN. I used to use asset_sync and s3 but I wanted to switch over to a CDN.
When I go to my Heroku App, I see that all the pages are just bare HTML. None of the JS or CSS is being loaded.
These are the errors I am getting from my Console:
Screenshot of console errors: http://i61.tinypic.com/15rxdsj.jpg
Also, I am not sure if I have set up my Origin Domain Name and Origin Path correctly on the Cloudfront Origin Settings.
Currently I am using my heroku app url as the Origin Domain Name and "/production/assets" as the Origin Path.
Production.rb file: http://pastebin.com/2dzLpGfE
I have been trying unsuccessfully for the past week to get the Heroku app to display the CSS and JS. I would greatly appreciate any insight. Thanks in advance!

Moving to Cloudfront isn't as drastic as change as you seem to think if you had everything working from S3. After all, Cloudfront simply distributes the contents of your S3 bucket to edge locations. This means you just have to let Rails know to look for the CDN and not S3.
There are a lot of things that could be going on. You could have misconfigured Cloudfront, which should be pointing to your S3 bucket as the origin. You should test that setup by checking to see an asset in the browser by using the Cloudfront URL. The main point is that Cloudfront should have no idea about your Rails app.
Meanwhile, you can still use AssetSync to push your assets to S3 "underneath" an assets path. You must also configure config.action_controller.asset_host as described here.

Related

Enabling Rails CloudFront on Heroku

I followed this article on Heroku to enable CloudFront on my Rails 5 app hosted on Heroku. However, it doesn't seem to be working for my images (which are hosted on S3).
I have tried setting the Origin Domain Name in AWS to both by S3 bucket (selected from the dropdown), as well as my app's domain name.
However, when I look at the source code, the images are still using the S3 URL instead of the being prefaced with the CloudFront URL which leads me to believe that something is not set-up right.
When I look at the source, I can see the some things are using the preface, such as my favicon https://mycloudfront.cloudfront.net/assets/favicon-28fde7db6babda6b94460b806d567abe4521f8dd77bc3741debadbf30eeecb19.ico.
I saw this post
Rails Cloudfront assets not served, but I'm using image_tag on the images showing the S3 URL in the source code.
in production.rb
config.action_controller.asset_host = "https://mycloudfront.cloudfront.net/"

Heroku + Rails4.2 : Cloudfront setup

I am trying to setup Cloudfront for my heroku app. The documentation seems to be lacking to stand independently.
Here are the steps I followed:
1. Setup Cloudfront in AWS console
2. Added cloudfront domain name to production.rb `config.action_controller.asset_host = 'XXXX.cloudfront.net'`
3. Set `config.assets.compile = true` in production.rb
4. Verified AWS_SECRET_ACCESS_KEY is correct in heroku config
5. I have added `gem 'rails_12factor', group: :production`
None of assets load anymore. Any step I am missing in the setup?
Update1:
In the chrome debugger the asset is correctly requested from cloudfront from this url: http://XXXXX.cloudfront.net/assets/application-22c7c249df1a24541d86603b0715eefe.css
However in the request header see a Status Code:302 Moved Temporarily. I am wondering if I have a redirect loop and how I can debug it.
Update2
Thanks everyone for the suggestions. Some more info:
When I try to download the asset from my app, I get a redirect to home page on browser but using curl I am able to get the asset. ex: curl 'http: //www.myapp.com/assets/application-c9a778bb55ad4152d956fd34fe6f7839.css'
The app doesnt use SSL. However I have still set Origin Protocol Policy to Match Viewer as per #Omar's suggestions
I tried to download the asset from my app on browser and am able to access the assets. ex: 'http: //www.myapp.com/assets/application-c9a778bb55ad4152d956fd34fe6f7839.css'
However trying to access the assets directly on cloudfront (d1ax5oefcdtdki.cloudfront.net/assets/application-c9a778bb55ad4152d956fd34fe6f7839.css) redirects it to myapp.com
Screenshots for cloudfront DS:
https://www.dropbox.com/s/bkg480d4it6zl2r/Screenshot%202015-12-06%2014.01.28.png?dl=0
http://glui.me/?i=7ah73hffrhvmpt7/2015-12-06_at_2.02_PM.png/
https://www.dropbox.com/s/dd4wwgm3md8w7qn/Screenshot%202015-12-06%2014.05.20.png?dl=0
For anyone else having issues debugging cloudfront.
The problem was Cloudfront had cached redirects (prob bec of wrong setup). After invalidating the cache I was able to force CF to fetch assets from my app and serve them.
When you request the asset for the first time, cloudfront checks whether the file is cached or not so for example you request:
http://XXXXX.cloudfront.net/assets/application-22c7c249df1a24541d86603b0715eefe.css
for the first time cloudfront will give a cache miss and then it will pull the file from it equivalent path from rails. So that the next time you request the same file, it will be already cached.
In order for this to work you need to make sure that you have everything setup correctly.
From rails side there is nothing much to do except setting the assets_host in production.rb. As you already have the rails_12factor gem there is no need to add the config.assets.compile = true. From the documentation of the gem you can see in the how section that it add serving static assets "the documentation".
From cloudfronts side that is where I think you are facing a problem, you need to set some settings to let cloudfront know how it can communicate with your rails app when the cache misses. In the cloudfront setting you need to check the
Origin Domain Name to be the url of your rails app.
Origin Protocol Policy to Match Viewer
Distribution State to Enabled
Also there are some other settings there that can help you optimize your content delivery caching.

Configuring a Heroku Rails app for CKEditor to work on Cloudfront

I'm using this gem to integrate CKEditor into my Rails app, with paperclip to handle image uploading.
I no longer want Heroku to serve my CKEditor-uploaded images anymore, so I'm switching to Cloudfront and found this tutorial.
As I understood (from the tutorial), I can use Cloudfront without using an S3 bucket, as Cloudfront will automatically fetch my precompiled static assets stored on Heroku. But I'm so confused:
Will image uploaded via CKEditor be included in the asset pipeline? So that when precompiled, will be served by Cloudfront?
The tutorial said I need to change all image links to <%= image_tag('...') %> so that it'll point to Cloudfront and work. But this is only possible when I hard-coded the image, not the case when a user uploaded one in his text and stored in the database. Am I wrong and how to solve it?
Will this method (not using S3 bucket) work for other "dynamic" images such as User's avatars, post's cover images, etc...?
I don't want to use S3 bucket as it will involve the use of asset_sync. Any help is appreciated, thanks!

When the protocol is https, Amazon S3 assets won't load, - Rails, Heroku

I set up asset_sync gem on heroku, following this URL: https://github.com/rumblelabs/asset_sync
The settings are working and I uploaded all the static assets at S3.
The problem is, when I open page through https protocol, can't access any of the assets, because the browser returns "This Connection is Untrusted". (same with Chrome & Firefox).
Every assets will be able to use after I admit access to s3 assets url. https://myapp.asset.s3.amazonaws.com/assets
Anyone had same problem? how to fix this problem?
The SSL certificate for s3 is a wildcard certificate, i.e. it is for *.s3.amazonaws.com. However a lot of certificate checking libraries define this to cover foo.s3.amazonaws.com but not foo.bar.amazonaws.com: wildcard certificates only go one level down.
The simplest solution is to pick a bucket name with no dots in it, e.g. myapp-assets.
Another solution is to access the files as https://s3.amazonaws.com/myapp.asset/assets/.... I believe you'd have to set config.assets.prefix to tell rails that the assets aren't in the normal location relative to the asset host.

Rails 3 automatic asset deployment to Amazon CloudFront?

Is there a gem or method available in Rails 3.1 that can upload assets to amazon cloud front automatically and use those instead of serving locally hosted ones? I guess it's easy to upload compiled assets manually and then change the rails app config to use that asset host, but when an asset is modified, the uploads to cloud front would need to be done manually again. Any good ways out there for this?
Definitely check out asset_sync on github. Or our Heroku dev centre article on Using a CDN asset Host with Rails 3.1 on Heroku.
There is quite a big performance improvement in using asset_sync vs a CDN custom origin, letting your application lazily compile assets in production or serving them precompiled directly off your app servers. However I would say that. I wrote it.
With asset_sync and S3 you can precompile assets meaning all the assets are there ready to be served on the asset host / CDN immediately
You can only require the :assets bundle in application.rb on precompile, saving memory in production
Your app servers are NEVER hit for asset requests. You can spend expensive compute time on, you know. Computing.
Best practice HTTP cache headers are all set by default
You can enable automatic gzip compression with one extra config
If you use Cloudfronts “Custom origin” option you do not need to upload anything, Cloudfront will fetch the assets from your server when needed. For details of setting this up see:
http://blog.ertesvag.no/post/10720082458
Take a look at https://github.com/rumblelabs/asset_sync - we're using it just to S3 but I guess the CloudFront part is pretty easy once the assets are on S3.
It's ends up being a rake task that you just add to execute in your deployment process.
another option would be https://github.com/moocode/asset_id, the readme has an example to use it with cloudfront.
It should work with rails 3.1 but I have only used it on 3.0.x.
Ss John said all solutions would end up being a rake task + a bit of logic to change the asset path in rails.

Resources