Rails Assets and CDN Issues (CSS, JS references) - ruby-on-rails

I am dealing with Rails 3.1.2, asset_sync and cludfront. I have installed asset_sync and precompiled all the assets. The problem I am facing is the following:
rake compiles combine javascript and css files into a application.[js|css].
In production mode the application is still referencing the original name but with the new cdn path and I get a 404 error.
this is production env file:
Griov4::Application.configure do
# Settings specified here will take precedence over those in config/application.rb
# Code is not reloaded between requests
config.cache_classes = true
# Full error reports are disabled and caching is turned on
config.consider_all_requests_local = false
config.action_controller.perform_caching = true
# Disable Rails's static asset server (Apache or nginx will already do this)
config.serve_static_assets = false
# Compress JavaScripts and CSS
config.assets.compress = true
# Don't fallback to assets pipeline if a precompiled asset is missed
config.assets.compile = true
# Generate digests for assets URLs
config.assets.digest = true
# Defaults to Rails.root.join("public/assets")
# config.assets.manifest = YOUR_PATH
# Specifies the header that your server uses for sending files
# config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache
# config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx
# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
# config.force_ssl = true
# See everything in the log (default is :info)
# config.log_level = :debug
# Use a different logger for distributed setups
# config.logger = SyslogLogger.new
# Use a different cache store in production
# config.cache_store = :mem_cache_store
# Enable serving of images, stylesheets, and JavaScripts from an asset server
# config.action_controller.asset_host = "http://assets.example.com"
# Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added)
# config.assets.precompile += %w( search.js )
# Disable delivery errors, bad email addresses will be ignored
# config.action_mailer.raise_delivery_errors = false
# Enable threaded mode
# config.threadsafe!
# Enable locale fallbacks for I18n (makes lookups for any locale fall back to
# the I18n.default_locale when a translation can not be found)
config.i18n.fallbacks = true
# Send deprecation notices to registered listeners
config.active_support.deprecation = :notify
config.action_controller.asset_host = "#{ENV['CDN']}"
end
This is my .env file
FOG_PROVIDER=AWS
FOG_DIRECTORY=
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
CDN=http://d3tf1w68p27174.cloudfront.net
RACK_ENV=production
my manifest file within js folder:
// This is a manifest file that'll be compiled into including all the files listed below.
// Add new JavaScript/Coffee code in separate files in this directory and they'll automatically
// be included in the compiled file accessible from http://example.com/assets/application.js
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// the compiled file.
//
//= require_tree .
my manifest file within css folder:
/*
* This is a manifest file that'll automatically include all the stylesheets available in this directory
* and any sub-directories. You're free to add application-wide styles to this file and they'll appear at
* the top of the compiled file, but it's generally better to create a new file per style scope.
*= require_self
*= require bootstrap.min
*/
Then I type: $bundle exec rake assets:clean assets:precompile
application.ss and application.js gets created but unfortunately the production application still refers to the original css/js files with the following path:
http://d3tf1w68p27174.cloudfront.net/assets/home-24d72d1643e0016381b14c19d90d9e74.css
http://d3tf1w68p27174.cloudfront.net/assets/home-74ac0007a6e42997f8210f80b99a203b.js
I checked both my local folder and the cdn folder and none of them contains those files.
asset_sync is working correctly because I can see the rest of the assets on my cdn folder.
I know it could be something related to the asset pipeline, but I can't figure out what it is.
Thanks for your help.

To ensure all of your assets reference the new asset host, make sure you’re using the Rails AssetTagHelper methods (like image_tag, stylesheet_link_tag, favicon_link_tag, etc).
If you are using background image references in your CSS, you can leverage the multiple asset-preprocessor support to ensure they also reference the new asset host.
For example, to enable multiple asset-preprocessing on "home.css", you can add the .erb extension to it changing it to "home.css.erb". This file will first be processed by ERB, then CSS, which means you can reference your assets as shown in the example below:
body {
background: url(<%= asset_path 'bg.png' %>);
}
You can take this further by doing something like "home.css.scss.erb".
See this and this for more info.

Related

Asset pipeline in production with Rails 7.0.0.alpha

Hey everyone this one has left me somewhat stumped and I feel like I have been going around in circles. I am trying to get my assets to be served from a CDN (in this case AWS/Cloudfront)
The assets are precompiled and deployed to the S3 bucket via CI server and that is working fine.
I have read the guides and believe I have set the config/environments/production.rb correcting as follows:
# Disable serving static files from the `/public` folder by default since
# Apache or NGINX already handles this.
# config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?
# Compress CSS using a preprocessor.
# config.assets.css_compressor = :sass
# Do not fallback to assets pipeline if a precompiled asset is missed.
config.assets.compile = false
# Enable serving of images, stylesheets, and JavaScripts from an asset server.
config.asset_host = ENV['RAILS_ASSET_HOST']
# Specifies the header that your server uses for sending files.
# config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache
# config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX
I have debugged that the environment variable RAILS_ASSET_HOST is set correctly to https://asset.mycdn.com but no matter what I do I continue to get the following error:
ActionView::Template::Error (The asset "application.css" is not present in the asset pipeline.
Any help appreciated. I am sure it is something stupid, just been staring too long!
From recollection, you need to have the generated manifest file on the app server, otherwise rails has no way of translating application.css into the corresponding application-SOME_SHA.css

rails 4 not using digests in asset filenames, but only in production

I have a Rails 4 app that was recently heavily upgraded (in terms of gem versions and some other things). Deploys have been working fine, but once we cleared out our tmp directories we noticed that assets stopped working in production. What's happening is for some reason in production mode, the helpers aren't using digests in any of the asset filenames (e.g. /javascripts/application.js instead of /javascripts/application-some-digest.js). This causes those assets to 404, since they do exist with their proper digest names in the public directory and Google App Engine is set up to independently serve static files for the public directory (which has always worked fine). What is really strange, though, is that in staging mode, the app is doing everything properly, so there is something about our production environment that is making the helpers not use digests.
Even weirder, though, is if I go RAILS_ENV=production rails console and do helper.asset_path 'application.js' I get the proper filename with the digest. What on earth could be going on?
And yes, we are doing RAILS_ENV=production rake:assets:precompile before deploying.
Here are the relevant parts from config/environments/production.rb:
config.eager_load = true
config.assets.cache_store = :dalli_store
# Don't force SSL because we need non-ssl cookies.
config.force_ssl = false
config.stripe_livemode = true
config.assets.digest = true
config.assets.compile = false
Here are the relevant parts from config/environments/shared.rb:
# Disable Rails's static asset server (Apache or nginx will already do this)
config.serve_static_files = false
# Compress JavaScripts and CSS
config.assets.compress = true
# Don't fallback to assets pipeline if a precompiled asset is missed
config.assets.compile = false
# Generate digests for assets URLs
config.assets.digest = true
# Precompile additional assets (application.js, application.css, and all
# non-JS/CSS are already added)
config.assets.precompile += ['zxcvbn.js', 'hammer.min.js', 'jquery.ba-throttle-debounce.min.js', 'mediaCheck.js', 'application-no-mq.css', 'lte-ie7.js', 'mailcheck.js', 'browserconfig.xml', 'main.css', 'oamm.js', 'oamm.min.js']
Here are the relevant parts from config/application.rb:
config.assets.precompile += %w( *.js ^[^_]*.css *.css.erb )
# Enable the asset pipeline
config.assets.enabled = true
config.log_level = :info
config.assets.precompile += ['rails_admin/rails_admin.css', 'rails_admin/rails_admin.js']
# Version of your assets, change this if you want to expire all your assets
config.assets.version = '1.0'
And finally, here are the relevant parts from config/environments/staging.rb which is somehow working fine:
# Speed up asset compilation on Heroku.
config.assets.cache_store = :dalli_store
config.eager_load = true
config.stripe_livemode = false

Font Awesome icons shows up as black squares on Heroku

I'm using the Font-Awesome-Sass gem with my Rails Project.
I followed the gem's instructions, and have included the #import into the application.css.scss. I'm also using the correct Rails syntax in the html to reference the icons. Everything works great locally, but as soon as I push to my staging Heroku environment, the icons just show as black squares.
Here is a snippet of staging.rb (the staging Heroku environment I was talking about)
# Code is not reloaded between requests.
config.cache_classes = true
config.eager_load = true
# Full error reports are disabled and caching is turned on.
config.consider_all_requests_local = false
config.action_controller.perform_caching = true
# Enable Rack::Cache to put a simple HTTP cache in front of your application
# Add `rack-cache` to your Gemfile before enabling this.
# For large-scale production use, consider using a caching reverse proxy like nginx, varnish or squid.
# config.action_dispatch.rack_cache = true
# Disable Rails's static asset server (Apache or nginx will already do this).
config.serve_static_assets = true
# Compress JavaScripts and CSS.
config.assets.js_compressor = :uglifier
# config.assets.css_compressor = :sass
# Do not fallback to assets pipeline if a precompiled asset is missed.
config.assets.compile = true
# Generate digests for assets URLs.
config.assets.digest = true
# Version of your assets, change this if you want to expire all your assets.
config.assets.version = '1.0'
# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
# config.force_ssl = true
# Set to :debug to see everything in the log.
config.log_level = :info
# Use a different cache store in production.
# config.cache_store = :mem_cache_store
# Enable serving of images, stylesheets, and JavaScripts from an asset server.
config.action_controller.asset_host = "//MYCLOUDFRONTHOSTINGURL-hidden-for-this-question"
# Enable locale fallbacks for I18n (makes lookups for any locale fall back to
# the I18n.default_locale when a translation can not be found).
config.i18n.fallbacks = true
# Send deprecation notices to registered listeners.
config.active_support.deprecation = :notify
# Disable automatic flushing of the log to improve performance.
# config.autoflush_log = false
# Use default logging formatter so that PID and timestamp are not suppressed.
config.log_formatter = ::Logger::Formatter.new
Is there something I'm missing?
Thanks for the help!
This happens when you have another font overriding your icon font. Search your CSS to see if there is another font-family:OtherFont!important;.
First make sure that your Font-awesome CSS is loaded, and font-urls point to the correct fonts.
Then explicitly specify your i.fa tags (which are used by Font-awesome to create the font) to
i.fa {
font-family:FontAwesome!important;
}
Worked great for me.
I had the same problem! Font awesome was working on local however when deployed to Heroku all icons appeared as a small white square. It was previously working without problem.
This worked for me: Add below line to layout file.
<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.1.0/css/font-awesome.min.css" rel="stylesheet">
Works fine now.

Rails asset caching -- cannot get max-age to set

I'm having trouble getting rails to set the max-age value for any of my CSS or JS assets. We're running rails 3.1, but we upgraded so I am quite possibly missing some obvious piece of configurations. At this point, I've flipped most of the configs I can find from true to false and back again with no luck.
Here is my current environment/production.rb
Ventura::Application.configure do
# Settings specified here will take precedence over those in config/application.rb
# Code is not reloaded between requests
config.cache_classes = true
# Full error reports are disabled and caching is turned on
config.consider_all_requests_local = false
config.action_controller.perform_caching = true
# Configure static asset server for tests with Cache-Control for performance
config.serve_static_assets = false
config.static_cache_control = "public, max-age=3600"
# Compress JavaScripts and CSS
config.assets.compress = true
# Don't fallback to assets pipeline if a precompiled asset is missed
config.assets.compile = true
# Generate digests for assets URLs
config.assets.digest = true
# Defaults to Rails.root.join("public/assets")
# config.assets.manifest = YOUR_PATH
# Specifies the header that your server uses for sending files
# config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache
# config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx
# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
# config.force_ssl = true
# See everything in the log (default is :info)
# config.log_level = :debug
# Use a different logger for distributed setups
# config.logger = SyslogLogger.new
# Use a different cache store in production
# config.cache_store = :mem_cache_store
# Enable serving of images, stylesheets, and JavaScripts from an asset server
# config.action_controller.asset_host = "http://assets.example.com"
# Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added)
# config.assets.precompile += %w( search.js )
# Disable delivery errors, bad email addresses will be ignored
# config.action_mailer.raise_delivery_errors = false
# Default mailer URL
config.action_mailer.default_url_options = { :host => 'http://ventura-production.herokuapp.com/'}
# Enable threaded mode
# config.threadsafe!
# Enable locale fallbacks for I18n (makes lookups for any locale fall back to
# the I18n.default_locale when a translation can not be found)
config.i18n.fallbacks = true
# Send deprecation notices to registered listeners
config.active_support.deprecation = :notify
end
And this is in my application.rb
# Enable the asset pipeline
config.assets.enabled = true
# Version of your assets, change this if you want to expire all your assets
config.assets.version = '1.0'
# Don't load resources when precompiling
config.assets.initialize_on_precompile = false
I am including the assets correctly, I think. Here's an example: <%= javascript_include_tag "client/jquery", "client/jquery-ui-1_8_18", "client/bootstrap_min", "client/jquery-select-menu", "client/jquery_tablesorter", "client/jquery_tablesorter_pager", "client/application" %>
And a partial trace on a request of any given page:
cache: [GET /assets/client/jquery-ui-1_8_18-d903da4c219079ca31f0ea1b23f89afc.css] fresh
cache: [GET /assets/client/bootstrap-2186f501bbd967564f2793c1c30aebc8.css] fresh
cache: [GET /assets/client/rg-5f04e577cfffd5dbcb8a1735ad211bd9.css] fresh
cache: [GET /assets/client/custom_charts-63eaad73c206c7ce6616c7f718be783f.css] fresh
cache: [GET /assets/client/bootstrap_min-afbee53fdd364c866cbd15abd6473012.js] fresh
cache: [GET /assets/client/jquery-select-menu-f2a3776430c5b4ead15173d0247f3f11.js] fresh
cache: [GET /assets/client/jquery_tablesorter-7fc613e34c891c852e2932f59bf91368.js] fresh
cache: [GET /assets/client/jquery_tablesorter_pager-141a886e7f35eb9f662b865516b23eca.js] fresh
cache: [GET /assets/client/jquery-689ca6a49fcbd1c3777b13d1abcc1316.js] fresh
cache: [GET /assets/client/application-6a61f272dd6a1ff7b5587435e67cd1bf.js] fresh
I should be able to avoid all these gets on every page-load. (and yes, I should not host most jquery stuff locally, on my to-do list)
From the Rails Configuration Guide (emphasis mine):
config.serve_static_assets configures Rails itself to serve static assets. Defaults to true, but in the production environment is turned off as the server software (e.g. Nginx or Apache) used to run the application should serve static assets instead. Unlike the default setting set this to true when running (absolutely not recommended!) or testing your app in production mode using WEBrick. Otherwise you won´t be able use page caching and requests for files that exist regularly under the public directory will anyway hit your Rails app.
I would try setting config.serve_static_assets = true if you haven't already.
Update: The Heroku Dev Center also recommends this:
To allow your application to properly serve, invalidate and refresh static assets several config settings must be updated in config/environments/production.rb. Allow Rails to serve assets with the serve_static_assets setting.

Rails compiles assets both with and without md5 hash, why?

I'm relatively new to RoR and I'm curious about why Rails compiles assets both with and without md5 hash for production?
I run bundle exec rake assets:clean then bundle exec rake assets:precompile
My production.rb file:
MyApp::Application.configure do
# Code is not reloaded between requests
config.cache_classes = true
# Full error reports are disabled and caching is turned on
config.consider_all_requests_local = false
config.action_controller.perform_caching = true
# Disable Rails's static asset server (Apache or nginx will already do this)
config.serve_static_assets = false
# Compress JavaScripts and CSS
config.assets.compress = true
# Don't fallback to assets pipeline if a precompiled asset is missed
config.assets.compile = false
# Generate digests for assets URLs
config.assets.digest = true
config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx
config.assets.precompile += %w(tos.js, tos.css)
config.i18n.fallbacks = true
config.active_support.deprecation = :notify
end
My application works with files with hashes in their names and it's the way it should be in my case :)
So I have two questions here:
1) Why is it happening when compiled?
Rails compiles assets both with and without md5 hash for production
2) What are these files (without hashes) for?
Maybe I don't get something, so please could someone explain.
The reason it does it is so that you can access the files without knowing the MD5 fingerprint (for example in a non-rails application, or a file within the rails app which isn't compiled or run by the rails stack (e.g. a 500/502 status error page). In this case you would have to compile the assets then change the css/js links in the static HTML files each time you updated the code (thus causing a change in the MD5 hash).
So instead rails produces 2 copies of each asset file, one with the fingerprint in the filename, the other without (e.g. application-731bc240b0e8dbe7f2e6783811d2151a.css, and application.css). The fingerprinted version is obviously preferred (see 'what is fingerprinting and why should I care' in the rails asset pipeline guide). But the non-digested version is there as a fallback.
As a final thought on the matter I'd take a read of the following pull request to the rails git repo: https://github.com/rails/rails/pull/5379 where they are discussing the pros and cons of the non-digested filenames, and the possibility of being able to turn off compilation of them.
HTH

Resources