Rails 4: assets not loading in production
I'm trying to put my app into production and image and css asset paths aren't working.
Here's what I'm currently doing:
- Image assets live in /app/assets/images/image.jpg
- Stylesheets live in /app/assets/stylesheets/style.css
- In my layout, I reference the css file like this:
<%= stylesheet_link_tag "styles", media: "all", "data-turbolinks-track" => true %>
- Before restarting unicorn, I run
RAILS_ENV=production bundle exec rake assets:precompile
and it succeeds and I see the fingerprinted files in thepublic/assets
directory.
When I browse to my site, I get a 404 not found error for mysite.com/stylesheets/styles.css
.
What am I doing wrong?
Update: In my layout, it looks like this:
<%= stylesheet_link_tag "bootstrap.min", media: "all", "data-turbolinks-track" => true %>
<%= stylesheet_link_tag "styles", media: "all", "data-turbolinks-track" => true %>
<%= javascript_include_tag "application", "data-turbolinks-track" => true %>
The generate source is this:
<link data-turbolinks-track="true" href="/stylesheets/bootstrap.min.css" media="all" rel="stylesheet" />
<link data-turbolinks-track="true" href="/stylesheets/styles.css" media="all" rel="stylesheet" />
<script data-turbolinks-track="true" src="/assets/application-0c647c942c6eff10ad92f1f2b0c64efe.js"></script>
Looks like Rails is not properly looking for the compiled css files. But it's very confusing why it's working correctly for javascripts (notice the /assets/****.js
path).
Solution 1:
In rails 4 you need to make the changes below:
config.assets.compile = true
config.assets.precompile = ['*.js', '*.css', '*.css.erb']
This works with me. use following command to pre-compile assets
RAILS_ENV=production bundle exec rake assets:precompile
Best of luck!
Solution 2:
I just had the same problem and found this setting in config/environments/production.rb:
# Rails 4:
config.serve_static_assets = false
# Or for Rails 5:
config.public_file_server.enabled = false
Changing it to true
got it working. It seems by default Rails expects you to have configured your front-end webserver to handle requests for files out of the public folder instead of proxying them to the Rails app. Perhaps you've done this for your javascript files but not your CSS stylesheets?
(See Rails 5 documentation). As noted in comments, with Rails 5 you may just set the RAILS_SERVE_STATIC_FILES
environment variable, since the default setting is config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?
.
Solution 3:
In /config/environments/production.rb
I had to add this:
Rails.application.config.assets.precompile += %w( *.js ^[^_]*.css *.css.erb )
The .js was getting precompiled already, but I added it anyway. The .css and .css.erb apparently don't happen automatically. The ^[^_]
excludes partials from being compiled -- it's a regexp.
It's a little frustrating that the docs clearly state that asset pipeline IS enabled by default but doesn't clarify the fact that only applies to javascripts.
Solution 4:
I was able to solve this problem by changing:
config.assets.compile = false
toconfig.assets.compile = true
in /config/environments/production.rb
Update (June 24, 2018): This method creates a security vulnerability if the version of Sprockets you're using is less than 2.12.5, 3.7.2, or 4.0.0.beta8
Solution 5:
For Rails 5, you should enable the follow config code:
config.public_file_server.enabled = true
By default, Rails 5 ships with this line of config:
config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?
Hence, you will need to set the environment variable RAILS_SERVE_STATIC_FILES
to true.