Rails asset caching -- cannot get max-age to set - ruby-on-rails

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.

Related

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

Elastic Beanstalk not loading assets for Ruby on Rails

I have a ruby on rails application that works locally in production locally but will not work when I upload it to EB, It breaks everything.
When it is local it looks like this
And here is my eb site, I have included on with the errors form the console, but you get the idea
Here is my production.rb
Rails.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
# Eager load code on boot. This eager loads most of Rails and
# your application in memory, allowing both threaded web servers
# and those relying on copy on write to perform better.
# Rake tasks automatically ignore this option for performance.
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 serving static files from the `/public` folder by default since
# Apache or NGINX already handles this.
config.serve_static_files = 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
# Asset digests allow you to set far-future HTTP expiration dates on all assets,
# yet still be able to expire them through the digest params.
config.assets.digest = true
# `config.assets.precompile` and `config.assets.version` have moved to config/initializers/assets.rb
# 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
# Use the lowest log level to ensure availability of diagnostic information
# when problems arise.
config.log_level = :debug
# Prepend all log lines with the following tags.
# config.log_tags = [ :subdomain, :uuid ]
# Use a different logger for distributed setups.
# config.logger = ActiveSupport::TaggedLogging.new(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'
# Ignore bad email addresses and do not raise email delivery errors.
# Set this to true and configure the email server for immediate delivery to raise delivery errors.
# config.action_mailer.raise_delivery_errors = false
# Enable locale fallbacks for I18n (makes lookups for any locale fall back to
# the I18n.default_locale when a translation cannot be found).
config.i18n.fallbacks = true
# Send deprecation notices to registered listeners.
config.active_support.deprecation = :notify
# Use default logging formatter so that PID and timestamp are not suppressed.
config.log_formatter = ::Logger::Formatter.new
# Do not dump schema after migrations.
config.active_record.dump_schema_after_migration = false
end
I have tried making
config.serve_static_files = true
config.assets.compile = true
False and it still doesn't work.
Any help?
I encountered a similar error when deploying my React on Rails 5 application to Elastic Beanstalk for production (was previously in Heroku in production). I came to solution from a different angle, adjusting the nginx default configuration. My problem was content from public/packs/ was not being served as packs/, which is how the <%= javascript_pack_tag 'application' %> was producing the link in app/views/layouts/application.html.erb. I added the following location directive at the end of /etc/nginx/conf.d/webapp_healthd.conf to remedy the issue:
location /packs {
alias /var/app/current/public/packs;
gzip_static on;
expires 1y;
add_header Cache-Control public;
add_header Last-Modified "";
add_header ETag "";
}
After ssh-ing into the app server, adding this directive, and sudo su; service nginx restart, static content from public/packs/ was correctly served as packs/. I believe this location directive can be added through a config file in .ebextensions to automate this change to the default elastic beanstalk nginx conf file.
This is due to Nginx config (in /etc/nginx/conf.d/webapp_healthd.conf).
When a request for /assets/anything is made, Nginx will look by itself in /var/app/current/public/assets.
This means any asset not present in /public/assets won't load
My ugly solution:
# config/application.rb
config.assets.prefix = '/some_other_path'
Note that this will slow assets requests as those will be processed by Puma and not directly by Nginx.
If you use the latest Amazon Linux 2 Elastic Beanstalk platform, then there's a much simpler way to solve this with platform configuration. See the full details here: https://stackoverflow.com/a/69103413/1852005

Browser fails to cache page assets for Rails 4 Site

When accessing our Rails 4 site, we used the Chrome developer tools to view our Network performance and to monitor the page load speeds of various assets. This showed that very few assets were/are being cached.
Files such as the application-.js and appliation-.css files, which we're positive have not changed between page loads, are also not being cached.
Within our config/environments/production.rb file we have configured the following:
# Code is not reloaded between requests.
config.cache_classes = true
# Eager load code on boot. This eager loads most of Rails and
# your application in memory, allowing both thread web servers
# and those relying on copy on write to perform better.
# Rake tasks automatically ignore this option for performance.
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
# Disable Rails's static asset server (Apache or nginx will already do this).
config.serve_static_files = false
# 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 = false
# 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'
# Set to :debug to see everything in the log.
config.log_level = :info
# 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
# Use default logging formatter so that PID and timestamp are not suppressed.
config.log_formatter = ::Logger::Formatter.new
Any thoughts on why this may be happening? Thanks.
This turned out to be an issue with the Browser settings that I was testing with. Quit and relaunched the browser and the static elements once again were cached as expected.

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 Assets and CDN Issues (CSS, JS references)

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.

Resources