Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails 5 + Heroku: Assets are not loaded in production, but works in localhost

My problem seems like any other classic asset pipeline issues on heroku which are already asked, but none of the solutions worked for me.

Question:

How to solve this problem?

Current Situation:

I have created a custom layout to include my vendor assets. Below is the code

#app/views/layouts/gentellela_theme.html.erb
<!DOCTYPE html>
<html>
  <head>
    <title>HMS</title>
    <%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => true %>
    <%= stylesheet_link_tag "css/custom", media: "all", "data-turbolinks-track" => true %>
    <%= stylesheet_link_tag "fullcalendar.print.min", :media => "print", 'data-turbolinks-track' => true %>
    <%= stylesheet_link_tag "dataTables.bootstrap4.min", media: "all", "data-turbolinks-track" => true %>
    <%= javascript_include_tag "application", "data-turbolinks-track" => true %>
    <%= javascript_include_tag "gentellela_theme", "data-turbolinks-track" => true %>
    <%= csrf_meta_tags %>

    <meta name="viewport" content="width=device-width, initial-scale=1">
  </head>

  <body class="nav-md">
    <%= render "layouts/sidenav" %>
    <%= render "layouts/topnav" %>

    <%= yield %>
    <%= render "layouts/footer" %>
    <%= javascript_include_tag 'js/custom', 'data-turbolinks-track' => true %>
  </body>
</html>

Problem:

I have two files under vendor/assets/components/gentelella/production/js/custom.js and vendor/assets/components/gentelella/production/css/custom.css. These files are loaded and working well in localhost, but they are not loading in Heroku

I can only see a warning like below in the browser console, but nothing more. No 404 errors either.

Loading failed for the with source “https://boiling-dusk-64956.herokuapp.com/javascripts/js/custom.js”

My config/application.rb looks like this

require_relative 'boot'

require 'rails/all'

# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)

module HMS
  class Application < Rails::Application
    # Settings in config/environments/* take precedence over those specified here.
    # Application configuration should go into files in config/initializers
    # -- all .rb files in that directory are automatically loaded.
    config.assets.paths << Rails.root.join('vendor', 'assets', 'components', 'gentelella', 'production')
  end
end

My config/initializers/assets.rb looks like this

# Be sure to restart your server when you modify this file.

# Version of your assets, change this if you want to expire all your assets.
Rails.application.config.assets.version = '1.0'

# Add additional assets to the asset load path
# Rails.application.config.assets.paths << Emoji.images_path

# Precompile additional assets.
# application.js, application.css, and all non-JS/CSS in app/assets folder are already added.
# Rails.application.config.assets.precompile += %w( search.js )
Rails.application.config.assets.precompile += %w( fullcalendar.print.min.css )
Rails.application.config.assets.precompile += %w( dataTables.bootstrap4.min.css)
Rails.application.config.assets.precompile += %w( gentellela_theme.js )
Rails.application.config.assets.precompile << Proc.new { |path, fn| fn =~ /vendor\/assets\/components\/gentelella\/production/ }

So I've referred to the related questions and tried to solve the issue, but to no avail. Below are my failed attempts

Attempt #1

Precompiled the assets locally with

RAILS_ENV=production bundle exec rake assets:precompile

and pushed the changes to heroku, but the problem persists.

Attempt #2

Added the below lines in config/application.rb

config.assets.enabled = true
config.serve_static_assets = true

and pushed the changes to heroku, but the problem persists.

Attempt #3

Modified config.assets.compile = false to config.assets.compile = true in config/environments/production.rb, but when pushing to heroku, the push failed with the below error

remote:  !     A security vulnerability has been detected in your application.
remote:  !     To protect your application you must take action. Your application
remote:  !     is currently exposing its credentials via an easy to exploit directory
remote:  !     traversal.
remote:  !     
remote:  !     To protect your application you must either upgrade to Sprockets version "3.7.2"
remote:  !     or disable dynamic compilation at runtime by setting:
remote:  !     
remote:  !     ```
remote:  !     config.assets.compile = false # Disables security vulnerability
remote:  !     ```
remote:  !     
remote:  !     To read more about this security vulnerability please refer to this blog post:
remote:  !     https://blog.heroku.com/rails-asset-pipeline-vulnerability
remote:  !
remote:  !     Push rejected, failed to compile Ruby app.
remote: 
remote:  !     Push failed
remote: Verifying deploy...
remote: 
remote: !   Push rejected to boiling-dusk-64956.

So, I upgraded the sprockets version as suggested and pushed the changes to heroku. This time the push has succeeded without any errors. Next I've run heroku run rake assets:precomplie and restarted the server. But now the application has crashed. Below is the heroku logs --tail info

2018-09-20T08:27:33.161369+00:00 heroku[router]: at=error code=H12 desc="Request timeout" method=GET path="/departments" host=boiling-dusk-64956.herokuapp.com request_id=fe446dfc-ea7c-4d38-8b6b-ec529e8db9eb fwd="27.7.94.242" dyno=web.1 connect=1ms service=30000ms status=503 bytes=0 protocol=https
2018-09-20T08:28:34.114593+00:00 heroku[web.1]: Process running mem=577M(112.7%)
2018-09-20T08:28:34.114685+00:00 heroku[web.1]: Error R14 (Memory quota exceeded)
2018-09-20T08:29:16.452991+00:00 heroku[web.1]: Error R14 (Memory quota exceeded)
2018-09-20T08:29:16.452911+00:00 heroku[web.1]: Process running mem=611M(119.5%)
2018-09-20T08:30:16.740081+00:00 heroku[web.1]: Restarting
2018-09-20T08:30:16.743963+00:00 heroku[web.1]: State changed from up to starting
2018-09-20T08:30:17.601536+00:00 heroku[web.1]: Stopping all processes with SIGTERM
2018-09-20T08:30:17.631815+00:00 app[web.1]: [2018-09-20 08:30:17] FATAL SignalException: SIGTERM
2018-09-20T08:30:17.631835+00:00 app[web.1]: /app/vendor/ruby-2.3.7/lib/ruby/2.3.0/webrick/server.rb:177:in `select'
2018-09-20T08:30:17.631838+00:00 app[web.1]: /app/vendor/ruby-2.3.7/lib/ruby/2.3.0/webrick/server.rb:177:in `block in start'
2018-09-20T08:30:17.631840+00:00 app[web.1]: /app/vendor/ruby-2.3.7/lib/ruby/2.3.0/webrick/server.rb:33:in `start'
2018-09-20T08:30:17.631843+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/rack-2.0.5/lib/rack/handler/webrick.rb:34:in `run'
2018-09-20T08:30:17.631841+00:00 app[web.1]: /app/vendor/ruby-2.3.7/lib/ruby/2.3.0/webrick/server.rb:164:in `start'
2018-09-20T08:30:17.631847+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/railties-5.0.0/lib/rails/commands/server.rb:79:in `start'
2018-09-20T08:30:17.631845+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/rack-2.0.5/lib/rack/server.rb:297:in `start'
2018-09-20T08:30:17.631851+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/railties-5.0.0/lib/rails/commands/commands_tasks.rb:85:in `tap'
2018-09-20T08:30:17.631849+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/railties-5.0.0/lib/rails/commands/commands_tasks.rb:90:in `block in server'
2018-09-20T08:30:17.631853+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/railties-5.0.0/lib/rails/commands/commands_tasks.rb:85:in `server'
2018-09-20T08:30:17.631856+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/railties-5.0.0/lib/rails/commands.rb:18:in `<top (required)>'
2018-09-20T08:30:17.631859+00:00 app[web.1]: bin/rails:4:in `require'
2018-09-20T08:30:17.631854+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/railties-5.0.0/lib/rails/commands/commands_tasks.rb:49:in `run_command!'
2018-09-20T08:30:17.697233+00:00 app[web.1]: [2018-09-20 08:30:17] INFO  WEBrick::HTTPServer#start done.
2018-09-20T08:30:17.631860+00:00 app[web.1]: bin/rails:4:in `<main>'
2018-09-20T08:30:17.632626+00:00 app[web.1]: [2018-09-20 08:30:17] INFO  going to shutdown ...
2018-09-20T08:30:19.862800+00:00 app[web.1]: I, [2018-09-20T08:30:17.637116 #4]  INFO -- : [fe446dfc-ea7c-4d38-8b6b-ec529e8db9eb] Completed 500 Internal Server Error in 194442ms (ActiveRecord: 2.6ms)
2018-09-20T08:30:19.862814+00:00 app[web.1]: F, [2018-09-20T08:30:17.643023 #4] FATAL -- : [fe446dfc-ea7c-4d38-8b6b-ec529e8db9eb]
2018-09-20T08:30:19.862817+00:00 app[web.1]: F, [2018-09-20T08:30:17.643123 #4] FATAL -- : [fe446dfc-ea7c-4d38-8b6b-ec529e8db9eb] ActionView::Template::Error ():
2018-09-20T08:30:19.862820+00:00 app[web.1]: F, [2018-09-20T08:30:17.647307 #4] FATAL -- : [fe446dfc-ea7c-4d38-8b6b-ec529e8db9eb]     3:    <head>
2018-09-20T08:30:19.862822+00:00 app[web.1]: F, [2018-09-20T08:30:17.647399 #4] FATAL -- : [fe446dfc-ea7c-4d38-8b6b-ec529e8db9eb]     4:      <title>HMS</title>
2018-09-20T08:30:19.862824+00:00 app[web.1]: F, [2018-09-20T08:30:17.647458 #4] FATAL -- : [fe446dfc-ea7c-4d38-8b6b-ec529e8db9eb]     5:     <%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => true %>
2018-09-20T08:30:19.862826+00:00 app[web.1]: F, [2018-09-20T08:30:17.647517 #4] FATAL -- : [fe446dfc-ea7c-4d38-8b6b-ec529e8db9eb]     6:     <%= stylesheet_link_tag "css/custom", media: "all", "data-turbolinks-track" => true %>
2018-09-20T08:30:19.862829+00:00 app[web.1]: F, [2018-09-20T08:30:17.647561 #4] FATAL -- : [fe446dfc-ea7c-4d38-8b6b-ec529e8db9eb]     7:     <%= stylesheet_link_tag "fullcalendar.print.min", :media => "print", 'data-turbolinks-track' => true %>
2018-09-20T08:30:19.862831+00:00 app[web.1]: F, [2018-09-20T08:30:17.647604 #4] FATAL -- : [fe446dfc-ea7c-4d38-8b6b-ec529e8db9eb]     8:     <%= stylesheet_link_tag "dataTables.bootstrap4.min", media: "all", "data-turbolinks-track" => true %>
2018-09-20T08:30:19.862833+00:00 app[web.1]: F, [2018-09-20T08:30:17.647647 #4] FATAL -- : [fe446dfc-ea7c-4d38-8b6b-ec529e8db9eb]     9:      <%= javascript_include_tag "application", "data-turbolinks-track" => true %>
2018-09-20T08:30:19.862835+00:00 app[web.1]: F, [2018-09-20T08:30:17.647690 #4] FATAL -- : [fe446dfc-ea7c-4d38-8b6b-ec529e8db9eb]
2018-09-20T08:30:19.862838+00:00 app[web.1]: F, [2018-09-20T08:30:17.647732 #4] FATAL -- : [fe446dfc-ea7c-4d38-8b6b-ec529e8db9eb] app/views/layouts/gentellela_theme.html.erb:6:in `_app_views_layouts_gentellela_theme_html_erb___843058433631945669_70285598017940'
2018-09-20T08:30:19.862840+00:00 app[web.1]: I, [2018-09-20T08:30:17.657292 #4]  INFO -- : [ab0d5f1c-d91e-4741-825e-97e1ce5443cf] Completed 500 Internal Server Error in 271041ms (ActiveRecord: 38.3ms)
2018-09-20T08:30:19.862841+00:00 app[web.1]: F, [2018-09-20T08:30:17.676144 #4] FATAL -- : [ab0d5f1c-d91e-4741-825e-97e1ce5443cf]
2018-09-20T08:30:19.862843+00:00 app[web.1]: F, [2018-09-20T08:30:17.676296 #4] FATAL -- : [ab0d5f1c-d91e-4741-825e-97e1ce5443cf] ActionView::Template::Error ():
2018-09-20T08:30:19.862845+00:00 app[web.1]: F, [2018-09-20T08:30:17.679494 #4] FATAL -- : [ab0d5f1c-d91e-4741-825e-97e1ce5443cf]     3:    <head>
2018-09-20T08:30:19.862847+00:00 app[web.1]: F, [2018-09-20T08:30:17.679561 #4] FATAL -- : [ab0d5f1c-d91e-4741-825e-97e1ce5443cf]     4:      <title>HMS</title>
2018-09-20T08:30:19.862848+00:00 app[web.1]: F, [2018-09-20T08:30:17.679834 #4] FATAL -- : [ab0d5f1c-d91e-4741-825e-97e1ce5443cf]     5:     <%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => true %>
2018-09-20T08:30:19.862850+00:00 app[web.1]: F, [2018-09-20T08:30:17.679898 #4] FATAL -- : [ab0d5f1c-d91e-4741-825e-97e1ce5443cf]     6:     <%= stylesheet_link_tag "css/custom", media: "all", "data-turbolinks-track" => true %>
2018-09-20T08:30:19.862852+00:00 app[web.1]: F, [2018-09-20T08:30:17.680159 #4] FATAL -- : [ab0d5f1c-d91e-4741-825e-97e1ce5443cf]     7:     <%= stylesheet_link_tag "fullcalendar.print.min", :media => "print", 'data-turbolinks-track' => true %>
2018-09-20T08:30:19.862853+00:00 app[web.1]: F, [2018-09-20T08:30:17.680220 #4] FATAL -- : [ab0d5f1c-d91e-4741-825e-97e1ce5443cf]     8:     <%= stylesheet_link_tag "dataTables.bootstrap4.min", media: "all", "data-turbolinks-track" => true %>
2018-09-20T08:30:19.862855+00:00 app[web.1]: F, [2018-09-20T08:30:17.680277 #4] FATAL -- : [ab0d5f1c-d91e-4741-825e-97e1ce5443cf]     9:      <%= javascript_include_tag "application", "data-turbolinks-track" => true %>
2018-09-20T08:30:19.862857+00:00 app[web.1]: F, [2018-09-20T08:30:17.683960 #4] FATAL -- : [ab0d5f1c-d91e-4741-825e-97e1ce5443cf]
2018-09-20T08:30:19.862859+00:00 app[web.1]: F, [2018-09-20T08:30:17.684030 #4] FATAL -- : [ab0d5f1c-d91e-4741-825e-97e1ce5443cf] app/views/layouts/gentellela_theme.html.erb:6:in `_app_views_layouts_gentellela_theme_html_erb___843058433631945669_70285598017940'
2018-09-20T08:30:19.862861+00:00 app[web.1]: Exiting
2018-09-20T08:30:20.300416+00:00 heroku[web.1]: Process exited with status 143
2018-09-20T08:30:26.455831+00:00 heroku[web.1]: Starting process with command `bin/rails server -p 51256 -e production`
2018-09-20T08:30:32.965279+00:00 app[web.1]: The PGconn, PGresult, and PGError constants are deprecated, and will be
2018-09-20T08:30:32.965301+00:00 app[web.1]: removed as of version 1.0.
2018-09-20T08:30:32.965303+00:00 app[web.1]: 
2018-09-20T08:30:32.965305+00:00 app[web.1]: You should use PG::Connection, PG::Result, and PG::Error instead, respectively.
2018-09-20T08:30:32.965306+00:00 app[web.1]: 
2018-09-20T08:30:32.965309+00:00 app[web.1]: Called from /app/vendor/bundle/ruby/2.3.0/gems/activesupport-5.0.0/lib/active_support/dependencies.rb:259:in `load_dependency'
2018-09-20T08:30:33.458524+00:00 app[web.1]: [2018-09-20 08:30:33] INFO  WEBrick 1.3.1
2018-09-20T08:30:33.458570+00:00 app[web.1]: [2018-09-20 08:30:33] INFO  ruby 2.3.7 (2018-03-28) [x86_64-linux]
2018-09-20T08:30:33.459164+00:00 app[web.1]: [2018-09-20 08:30:33] INFO  WEBrick::HTTPServer#start: pid=4 port=51256
2018-09-20T08:30:33.797414+00:00 heroku[web.1]: State changed from starting to up

So, I'm unable to detect why the application has crashed. Am I on the right track to solve my problem? Any help is appreciated. TIA

Update #1:

I got my app running and followed @Maxence approach. Now I can see 404 error messages for both the files

ActionController::RoutingError (No route matches [GET] "/stylesheets/css/custom.css") 

ActionController::RoutingError (No route matches [GET] "/javascripts/js/custom.js")

Update #2:

The logical paths for those files from sprockets-manifest file are below

gentelella/production/js/custom.js

and

gentelella/production/css/custom.css
like image 393
Pavan Avatar asked Sep 20 '18 08:09

Pavan


2 Answers

Well I have had quite a few problems with asset pipeline in production like you.

First : Dont compile assets at Heroku. Whether you do through the CLI heroku run rake assets:precomplie or through your production file config.assets.compile = true. It has not worked for me either.

Just use the recommended config.assets.compile = false. It will also make your deploy much faster because everything has been precompiled locally and your slug will be slimmer too.

So basically just do a RAILS_ENV=production bundle exec rake assets:precompile locally. This will create fingerprinted assets in your public/assets folder. It will also create a .sprockets-manifest file in this folder.

sprockets_manifest is the table of correspondence between your fingerprinted assets and the non fingerprinted assets referred to by the application helpers image_tag etc .. (You can open the manifest file, it is very interesting and helped me understand the problems I had)

Now you should be able to see all your assets fingerprinted in the public/assets folder. If some are missing you should check your assets.rb file and make sure you have included all files you need. (Precompiling method only precompiles what is mentionned in this file)

Basically from now on, your app is fine though I have found a few things that could prevent a good matching of assets by the manifest file / sprockets :

  • in your helpers, always mention the file type image_tag(splash) should be changed to image_tag(splash.jpg). It is because your manifest file adds the file type to the logical path, and rails doesn't guess it automagically. You should do the same with javascript_include_tag "gentellela_theme" and change it to javascript_include_tag "gentellela_theme.js". Or javascript_include_tag 'js/custom' to javascript_include_tag 'js/custom.js'
  • If you use SASS make sure your css files are properly named whatever.css.scss and not whatever.scss. I am using sass helpers in my css files and my files bad naming was breaking the matching by the manifest.

Then you should be good

EDIT

As per comments below, if you have changed the assets name with full name+file type (splash changed to splash.jpg for example) and the file is still not showing. Check the logical path of that specific asset in the manifest file. And replace the name of the asset by the logical path. The logical path disambiguates asset names.

EDIT 2

This thread aonly concernes Sprockets 3.X. Sprockets 4 / Webpacker works differently

like image 130
Maxence Avatar answered Oct 10 '22 09:10

Maxence


With all the correct config I was having this same issue (using heroku config that comes with the thoughtbot/suspenders gem) because I was using url instead of image-url in my css.

I had to change references in my css to set background images like this:

.my-div {
  background-image: image-url('some-image.jpg');
  background-size: cover;
}

And my deployed app loaded the images from the app/assets/images directory the same as on localhost.

like image 21
DannyRosenblatt Avatar answered Oct 10 '22 09:10

DannyRosenblatt