Why does a rails app on heroku serve assets via all.css and locally via individual files
This is the result of calling :cache => true on your stylesheet link tag.
:cache => true takes all of the stylesheets provided and concatenates them into one file called all.css.
The reason you're only seeing this on your Heroku deployment is because it calls the concatenated all.css only when the Rails application is running in production mode.
So for example let's say I have three stylesheets and I include them in my header:
= stylesheet_link_tag "application", "jquery-ui", "style", :cache => true
When in development, this will include application.css, jquery-ui.css, and style.css (in that order).
In production, it will concatenate all of the CSS from the three files (in the order provided) into one single file called "all.css", which will be the only CSS file included.
The benefit is making fewer HTTP requests in production and ideally a smaller file size for your included CSS, which should hopefully speed up page load.
Edit As Casper points out in the comments, Heroku has a read-only filesystem.
You might want to look at Heroku Asset Packager for a Heroku-specific solution.
stylesheet_link_tag(:all) generates reference to `all.css` on Heroku
Heroku is doing some special handling of asset files, see for example:
http://devcenter.heroku.com/articles/rails3 and
Why does a rails app on heroku serve assets via all.css and locally via individual files especially the final comment about :cache => true
working now and about File.open
operations not working.
They aren't expecting your use case as the most common, so it is possible that there is some bug in their handling. I would try explicitly setting :cache => false
and :config => false
Rails serves old css file in production
you just forgot 1 step:
git add -A
git commit -m "message"
git push origin your-git-branch
git push heroku master
After last command heroku will automatically run bundle install and setup your project/app for running in production mode.
Vendor assets not showing in heroku staging environment
So after some trial and error and getting feedback, below are some take away that I hope can help others in the future. The short of it is that, if you face any problem, always refer to Rails Asset Pipeline. This is because different rails versions has different methods. At the point of this answer, mine is Rails Version: Rails 4.2.0
. Ruby Version: ruby 2.1.3p242 (2014-09-19 revision 47630) [x86_64-darwin13.0]
Do note that this answer applied to my situation, may vary with yours.
My Problem Statement:
I bought a bootstrap template online and would like to incorporate it to my application. Below are the following steps I took to resolve the problem.
- Put files into vendor/assets - I cut and paste all the templates into my vendors/assets folder. All of the assets are properly arranged into their respective fonts folders, images folders, javascript folders and stylesheets folder.
- Only keep what I need - I removed the files that I do not need and only keep those that I need. This requires some reading of the vendor files.
- Ensure correct assets path - after which I went through each each files and ensure that the files are referencing the assets correctly. Any css files that has image and font references, I changed it to css.erb format, then put
<%= asset_path(...) %>
intourl(...)
. Note that there are various ways to do this i.e. use font_path or image_path, use css.scss instead of css.erb etc. Please refer to documentation from asset pipeline. I also removed any@import url('<your file>.css');
cause I will be using*= require <your files>
later - Config application.js and application.css in app/assets - I then key in "require " into application.js and application.css manifest respectively based on the names of the files I have in my vendor/assets folder. D note that the order is important. The manifest reads from top to bottom. Therefore, always ensure pre-requisite files are kept above files that depends on it. For example, I have a default.css file that depends on font.css, hence
*= require font.css
comes before*= require default.css
. - Create your view - then I created a some html.erb views files with controllers and routes.
- Test development locally - Launch the app locally through
rails s
. If you put the files correctly in their respective folders in vendor/assets. Your application should show up nicely. Else, please refer to the instructions above and try again. - Config to test production locally - to test production locally, first, go to your secrets.yml file and change the production secret_key_base to the one secret_key_base from your development (IMPORTANT to revert this back to ENV once you are done testing),
- Precompile and open rails app in production locally - Once you have configured, run
RAILS_ENV=production rake assets:precompile
in the
terminal. You should see your assets being precompiled. Once the
precompile is done, you should be able to find an assets folder in
your public folder (your images, videos and fonts assets should each
have their own files, whilst all css and js will be cramped into one file asapplication-<md5>.css
andapplication-<md5>.js
respectively). If this didnt workout properly, your precompile fails. It is most probably due to css or
js syntax error, go back and check the files and make the changes.
If you have made any corrective changes, please runrake assets:clobber
to remove the public/assets then run the production precompile again. Once all is good, run the following command in your terminalrails s -e production
, this
opens up your server locally but in production environment instead
of dev environment. When running localhost:3000 if your secret_key_base is not copied properly, you will see an error in your browser asking you to make changes to the secret key. Viewing localhost:3000 in browser - If your view in local production is different from that of your local development view. For example, most of the css did not show up properly, troubleshoot by
- right click on the parts of the website that is not reflected properly, click on
inspect element
, you should be able to see 404 errors. this means that your code or assets in .css and .js is not referenced or configured properly. go back to point 8 and redo. - check your rails server logs to find if there are any
ActionController::RoutingError (No route matches [GET] "/assets/...
. this means that your code or assets in .css and .js is not referenced or configured properly. go back to point 8 and redo.
- right click on the parts of the website that is not reflected properly, click on
Pushing to heroku - Once everything is good locally, you can now push to heroku. because you ran the precompile for production env locally, you will see that during your push to heroku, heroku will state something like
remote: Detected manifest file, assuming assets were compiled locally
. else, heroku will have to precompile for you. Note that heroku use rails_12factor gem in production. Additionally, these gems, sass-rails, coffee-rails, uglifier, come in default when you created your rails app which is essential for your asset pipeline.
Things I did not do to resolve my problem:
Though the methods below are valid,
I DID NOT use
config.serve_static_assets = true
for application.rb, production.rb or staging.rbI DID NOT ran
rake assets:precompile
I DID NOT ran
heroku run rake assets:precompile
I DID NOT put
Rails.application.config.assets.precompile += %w( *.css *.js )
in config/initializers/assets.rbI DID NOT resort to using
config.assets.compile = true
I DID NOT use
config.assets.paths << Rails.root.join("lib", "videoplayer", "flash")
in config/application.rb
Other links that could be helpful:
No route matches [GET] /assets
https://github.com/FortAwesome/font-awesome-sass/issues/48
Things I could not explain
This solution only worked when I recreated a new rails app. My old rails app did not work as when I ran precompile, the css and js files in public/assets were not in one application-<md5>.css
and application-<md5>.js
respectively. instead, they were scattered to their own font.css, default.css etc etc, as seen from "Output below" shown above. Will be doing more research to get down to the bottom of this.
I hope my answer above helped. Do give feedback if I made any mistakes or missed out anything.
Heroku staging environment not deploying all images and CSS
Precompilation
All of my images are in assets/images
You must remember that Heroku relies on precompiled
assets - so it will look in the public/assets/images
, or public/images
folder
When you're using bash
to see whether the files exist, it would be far more robust to look in the /public/images
folder, as this is where the precompiled assets would normally sit anyway
Fix
There are other subtleties such as different fonts and colours of
progress bars that aren't being deployed properly
This could be a number of issues which are causing this:
- Your assets may not be present
- Your references to the assets may be incorrect
What I would do (and have done before) is firstly to precompile your assets locally, as david
recommended. You can do that relatively simply:
$ rake asssets:precompile RAILS_ENV=production
This will populate your app's public
folder with the relevant assets, which will be referenced by your various path helpers
-
Secondly, I would make sure those assets are being referenced properly. The way to do this is to use the various path helpers
which are embedded inside Rails - a prime example being asset_path
/ asset_url
:
#app/assets/stylesheets/application.css.scss
.test {
background: asset_url("test.png");
}
This references the files regardless of whether they are precompiled or not; meaning that it will give you the ability to reference them in production. I would make sure your asset files have all the correct references in order to get things working again
Rails 5 + Heroku: Assets are not loaded in production, but works in localhost
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 toimage_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 withjavascript_include_tag "gentellela_theme"
and change it tojavascript_include_tag "gentellela_theme.js"
. Orjavascript_include_tag 'js/custom'
tojavascript_include_tag 'js/custom.js'
- If you use SASS make sure your css files are properly named
whatever.css.scss
and notwhatever.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
Can't get CSS working on Heroku using Rails 4 with bootstrap-sass gem
I just now (June 13 2013)got this answer from Heroku devs whose support guided me across the barriers.
This is how I got my css display from localhost working in my Heroku app.
"All you need to do is turn on asset serving in production and set the logger to stdout to get Rails4 to work on Heroku. We are currently working on smoothing out the deploy process for Rails 4 apps but for the meantime, you can just change those lines in your code and you won't need those gems." (Thanks Bret and Neil great news)
In /config/environments/production. set:
config.cache_classes = true
config.serve_static_files = true
config.assets.compile = true
config.assets.digest = true
I do not know about the stdout in logger so can't check that.
Do a git add . and git commit.
Make sure that /config/database.yml has:
production:
adapter: postgresql
encoding: unicode
database: Your_appname_production
You will need this info for the env command below.
Make sure you have gem 'pg' in production in your Gemfile
Do another git commit.
Run this command in a terminal in your app on one line:
env RAILS_ENV=production DATABASE_URL=postgresql://user:pass@127.0.0.1/Your_app_name_production bundle exec rake assets:precompile 2>&1
Where DATABASE_URL=postgresql is identical to your production adapter in the yml file
and Your_app_name_production is specified because Heroku only seems to run production.
I was advised against and did not need:
group :production do
gem 'rails_log_stdout', github: 'heroku/rails_log_stdout'
gem 'rails3_serve_static_assets', github: 'heroku/rails3_serve_static_assets'
end
It errors out in bundle install and Heroku.
Don't know if this helps but I also added production to
Bundler.require(*Rails.groups(assets: %w(development test production)))
Can't remember where I saw that advice.
HTH
Arel
heroku - rails 3.1 - asset pipeline
Okay, I finally figured this one out. After looking through http://guides.rubyonrails.org/asset_pipeline.html some more, I realized that I needed to add in:
//= require custom
to the application.css file. I entered this outside of comments and this fixed my problem. I was able to precompile locally and everything worked perfectly on Heroku after that. Thank you to everybody that helped me get there.
Related Topics
Cannot Load Such File -- MySQL2/2.4/Mysql2 (Loaderror) - Windows
How to Use Views and Layouts with Ruby and Erb (Not Rails)
Writing an Activerecord Adapter
Understanding Namespaces in Ruby
Redirect_Uri_Mismatch. Login with Google Using Ruby on Rails
How to List the Available Variables in an Ruby Erb Template
How to Install Rails with Jruby
Does the Order of Gems in Your Gemfile Make a Difference
Issues Installing Ruby and Rails and Devkit on Windows 7 X64 - Fix Needed
Converting a Unique Seed String into a Random, Yet Deterministic, Float Value in Ruby
How to Ensure Ruby Gems Are Installed in Right Place to Be Executed by Bundler
Ruby If VS End of the Line If Behave Differently
Failure: Expected 0 to Be >= 1 on Ruby on Rails
How to Make a Class Whose Constructor Looks Like the Constructor of a Built-In Class