Heroku does not precompile assets when deploying - ruby-on-rails

It very clearly says in its documentation that it would do this if I don't precompile them locally.
And truthfully, I have no interest in precompiling these locally.
What I've had in production.rb, I've duplicated in application.rb
In my production.rb :
config.serve_static_assets = false
config.assets.compile = false
config.assets.precompile << 'application.js'
config.assets.precompile << 'application.css'
config.assets.precompile << 'screen.css'
Then I deploy, and that returns :
-----> Compiled slug size: 52.4MB
-----> Launching... done, v28
http://myapp.herokuapp.com deployed to Heroku
So it "compiled" something, right? Except no go, I go to the site and the .css and .js files are blank.
In order to precompile this locally, I am required to comment out in bootstraps_and_overrides.css the line :
#import "screen.css.scss";
Then it precompiles locally, and my local machine will not load the css correctly, but remotely it will actually work correctly.
So my method of deployment now is comment out that line of code,
bundle exec rake assets:precompile
git add .
git commit -m "Adding public/assets"
git push heroku development:master
Then ( unfortunately! ) :
bundle exec rake assets:clean
And then uncomment that line of code in my .css.

Some things to check
You're on Cedar, right? Heroku only supports this behavior on Cedar.
You're on Rails 3, right? Heroku doesn't support precompiling assets on Rails 4.
You have asset pipeline turned on, right? in config/application.rb you need the line config.assets.enabled = true
You have to not have a public/assets folder. On deployment Heroku decides whether or not to precompile based on whether this folder is present (even if it's empty).
If the pipeline is on and you don't have an assets folder, then pre-compilation must be failing.

Try changing to this. I hope this will help you.
In config/environments/production.rb
config.assets.compile = true
config.assets.digest = true

You might be on the wrong Heroku stack. Make sure you specify stack Cedar when you create apps that use the asset pipeline.
heroku create -stack cedar

The reason it would not deploy was because of Google fonts. Moving the file to your application.css such as :
*= require_self
*= require_tree .
*/
#import url(http://fonts.googleapis.com/css?family=Special+Elite);
Will allow the app to deploy, and for the fonts to work.

Related

Ruby on Rails 4.2 Asset pipeline not minifying/compressing the application-fingerprinted.js JS file

I have a ruby on Rails 4.2 app and am facing a "hair-tearing" issue for long 2 days about my asset pipeline. My prod is hosted on Heroku and I directly mention this here as I think it might be relevant I have them gem 'rails_12factor', group: :production
I read and tried the suggestions of the (too) numerous SO questions about Rails assets not compiling but none worked as I'll describe further down.
The issue observed which led me to this SO question is that my my javascript application.js file was NOT minified in production.
How do I know? the white spaces are still here, the comments have not been removed, well the applciation.js, contrary to my application.css, is just a concatenatation of all js files but NO compressing/minifying has been done.
Most questions on SO deal with issues where neither images, css or js is minified/precompilied but my situation is peculiar to the extent that images, css are precompiled/minified, but only js is a problem and is not minified.
Is there a problem with my js? (see below for some experiments I tried to find out the reason of the bug) Seems not
My set up below will show you how I deal with assets (to the extent of my beginner understanding) : I use guard to constantly monitor any change and precompile stuff and put the resulting/generated application-tr56d7.css (fingerprinted) and application-45dsugdsy67.js ((fingerprinted) inside public/assets and then when I deploy on git, it pushes all changes , including the precompiled/minified files and then when I push to Heroku, my production asset settings say to Rails to deploy my already precompiled assets. I'm a beginner and struggled with understanding all the numerous dev/prod environment assets settings but I think that is what is defined in the code you'll find further down.
I know all this process it's working because everytime i change a file when I can find a new application-tr56d7.css and a new application-45dsugdsy67.js(examples of course) (along with a new css.gz and.js.z which must be the binary stuff)
Every time I change a js file for example, guard make his job and I can read something like:
I, [2018-02-09T09:53:41.140165 #130534] INFO -- : Writing /home/mathieu/rails_projects/my_app/public/assets/application-af0ab4a348e4f5545c844cfac02a0670.js
The new generated application.css and application.js files can then be found in public/assets folder: for example
/public/assets/application-1021e7d2ea120fe40c67ec288f1c6525.js
/public/assets/application-1021e7d2ea120fe40c67ec288f1c6525.js.gz (binary: just a list of numbers...)
/public/assets/application-753e1d0958f76ae233a460ad47606790.css
/public/assets/application-753e1d0958f76ae233a460ad47606790.css.gz (binary: just a list of numbers...)
So when I observed that in production the css was application-753e1d0958f76ae233a460ad47606790.css minified but not the application-1021e7d2ea120fe40c67ec288f1c6525.js js, I went to see on
public/assets and here too I noticed the same thing:
the css files generated by guard such as /public/assets/application-753e1d0958f76ae233a460ad47606790.css css are minified
but the js files genrated by gyard are NOT minified
So I think that, but I'm not sure, it's not a Heorku specific problem, it's just that even before pushing it to Heroku, my js file hosted on public/assets should be but is not minified.
What i tried to debug this (spoiling the suspenese:all failed):
tried to say explicitly in assets.rb to compile application.js not work => Result: js still not minified locally and not on production website on heroku
# It is recommended to make explicit list of assets in config/application.rb
config.assets.precompile = ['application.js']
tried cleaning all old stuff by rake :assets clobber => Result: js still not minified locally and not on production website on heroku
tried cleaning old stuff by changing version
assets.rb: changed => Result: js still not minified locally and not on production website on heroku
config.assets.version = '1.0'
into
config.assets.version = '1.1'
tried to change all the various dev and prod asset settings => Result: js still not minified locally and not on production website on heroku
config.serve_static_assets = true and tried false
tried also so many different settings for both files but none worked.
tried to compile in local and in prod => Result: js still not minified locally and not on production website on heroku
rake assets:precompile RAILS_ENV=production --trace
Also tried local:
rake assets:precompile
2 weirdest attempt:
after all my attempts at making this work by modifying the asset pipeline settings which all failed, I thought maybe there 's a tricky javascript error somewhere breaking silently the minification/compressing made by guard (which also be silent in terms of page load as no error appear on chrome dev tools when i load my pages but who knows...read on some SO questions some strange effect of comments on the asset pipeline)', so
I decided to comment ALL my js files inside assets/javascripts/! nothing left: and even removed the js that ends up in the pipeline but injected by a gem (so not visible in my folder app/assets/javascripts) such as jquery gem: and create 2 very basic js files
that would be the only remaining files...
well still : => Result: js still not minified locally and not on production website on heroku
Did again the same test as above but here went even further: I emptied (deleted all the content) of all the js files inside my assets/javascripts and removed form application.js all the gems to only leave require directory , and then created 2 very simple js files to check if it was minified now....
and still same result: js still not minified locally and not on production website on heroku
A test that kind of worked
doing rake assets:clobber then the push (git add, git commit, git push, git push heroku paster) DOES compile the js BUT unfortunately it creates other issues: it sends to the production an OLD version of the js (I know because i put a alert message inside the js and it's not the latest one!). What does it reveal about the bug that rake assets:clobber kind of debug it?
EDIT
I made it work but with quite a demanding process:
leveraging some people saying there is no compilation if you don't change css or js (see https://stackoverflow.com/a/7988689/1467802), I tweaked the previous process: (change sth in the js file, rake assets:clobber, git add, git commit, git push, git heroku master) and it works: it cpmpiles and sends the latest js file!
Isn't there any way not to have to remeber eveyr time to change sth inside the js to ensure compilation ?
I'm out of ideas. Maybe my settings are just wrong and as a beginner, I'm missing something obvious.
The weirdest poart is: my cs is minified! why not the js????
My codebase
/config/environments/development.rb
MyApp::Application.configure do
# Do not compress assets
config.assets.compress = false
# Expands the lines which load the assets
config.assets.debug = true
config.serve_static_files = false
end
/config/environments/production.rb
MyApp::Application.configure do
# 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 removed when switch from Rails 3.2 to Rails 4
config.assets.js_compressor = :uglifier
config.assets.js_compressor = Uglifier.new(
# Remove all console.* functions
:compress => { :drop_console => true }
) if defined? Uglifier
config.assets.css_compressor = :sass
# 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.force_ssl = true
end
/config/initializers/assets.rb
Rails.application.configure do
# Precompile additional assets.
# application.js, application.css, and all non-JS/CSS in app/assets folder are already added.
# related to deployment pb with active admin
config.assets.precompile += %w[admin/active_admin.css admin/active_admin.js]
# for ckeditor: github.com/galetahub/ckeditor
config.assets.precompile += %w( ckeditor/* )
# Version of your assets, change this if you want to expire all your assets
config.assets.version = '1.0'
end
/config/application.rb
require File.expand_path('../boot', __FILE__)
require "active_record/railtie"
require "action_controller/railtie"
require "action_mailer/railtie"
require "active_resource/railtie"
require "sprockets/railtie"
if defined?(Bundler)
# If you precompile assets before deploying to production, use this line
Bundler.require(*Rails.groups(:assets => %w(development test)))
end
module MyApp
class Application < Rails::Application
config.autoload_paths += %W(#{config.root}/lib)
# Enable the asset pipeline
config.assets.enabled = true
end
end
/Guardfile
# More info at https://github.com/guard/guard#readme
require 'active_support' # edded this due to a bug where guard did not load github.com/rails/rails/issues/14664
require 'active_support/core_ext'
require 'active_support/inflector'
# Make sure this guard is ABOVE any other guards using assets such as jasmine-headless-webkit
# It is recommended to make explicit list of assets in `config/application.rb`
# config.assets.precompile = ['application.js', 'application.css', 'all-ie.css']
# update dec 2014- added :runner => :cli because of a know bug on guard rail assets
# if bug is solved i can remove the part :runner=> cli
guard 'rails-assets', :run_on => [:start, :change], :runner => :cli do
watch(%r{^app/assets/.+$})
watch('config/application.rb')
end
assets/javascripts/application.js
//= require jquery
//= require jquery.turbolinks
//= require jquery_ujs
//= require jquery.cookie
//= require cloudinary-jquery.min
//= require twitter/bootstrap
//= require paloma
//= require html5shiv-printshiv
//= require storageService
//= require turbolinks
//= require_directory .
Terminal process when deploying after, for example chagning some js files and waiting guard has notified me it has finished its precompilaiton job:
git add --all
git commit -a -m "fix issue with asset pipeline"
git push
git push heroku master
I know what I am going to say is not conventional, but your aproach hasn't been so explicit, you should try adding the explicit compress call you have made false in development
/config/environments/production.rb
MyApp::Application.configure do
# Compress assets please
config.assets.compress = true
# ... other stuff
end
After that clean your assets and regenerate them with
$ bundle exec rake assets:clobber
$ RAILS_ENV=production bundle exec rake assets:precompile
If I understand this correctly, you can replicate this issue locally, so the Heroku factor is irrelevant.
However, it sounds like you are compiling the assets locally, committing them to repository, then pushing to Heroku. First of all, I'd avoid this and lean on letting Heroku do the static asset compilation during deploy.
Regardless, if I understand correctly that this is what you are doing, I think it may because when you run rake assets:precompile, you may be compiling them in dev mode, which will use your config/development.rb configuration, which has config.assets.compress = false. I'm not sure why some of your files are compressed while others aren't, other than it may simply be related to how recently you've modified the source files.
In any case, try running:
$ rake assets:clean
$ rake assets:precompile RAILS_ENV=production
I suspect you will have issues booting the app in production mode locally (e.g. if you don't have database credentials configured appropriately or something), which is another reason why I would not precompile assets locally prior to deploy. However, this may prove or disprove if the active environment is a factor in your issues.
In fact, you could try running this on the Heroku dyno instead, which will be setup for production already:
(local)$ heroku run bash
(heroku)$ rake assets:clean assets:precompile RAILS_ENV=production
(heroku)$ less public/assets/application-*.js # see if this is compressed
Let me know what you discover here and I can revise my answer if that doesn't change the equation for you

Ruby on Rails assets not being precompiled on Heroku

I have a project that works in the local development environment but breaks when it is uploaded to Heroku. When visiting my project on Heroku, I notice that I get 404 responses from the server saying that it could not find my css and js files. I have done some searching and found out that Heroku is not precompiling my assets. The project will work fine until Heroku puts my project to sleep. Upon waking the project in Heroku, the css and js are broken.
The project is using Rails 4.2.4, I have made sure to to include config.serve_static_assets = true in my config/application.rb and gem 'rails_12factor', group: :production in my Gemfile.
The css and js only breaks when Heroku puts the project to sleep due to inactivity. Does anyone know how to have Heroku automatically precompile assets when it is awaken from sleep?
I had similar issues before, my best bet was to precompile in local and then push to heroku. Configure your production.rb as follows:
config.serve_static_files = false
config.assets.compile = false
then in your console precompile as follows:
rake assets:precompile RAILS_ENV=production
This will precompile everything in public/assets commit your changes and push to heroku.
Also reset your assets cache for avoid any inconsistence:
rake assets:precompile RAILS_ENV=production
The above will force all your public/assets directory to rebuild when you run precompile command.
If your issue is with assets recompilation my answer should solve it, if you still have issues then you are doing something wrong or the issue does not have anything to do with assets precompilation.
We set the configuration values of above to false because now you are sending the precompiled files to the repo, so we do not serve static files nor fallback assets pipeline if something is missing, we are going everything in local.
Gemfile
gem 'rails_12factor', group: :production
application.rb
By default Rails 4 will not serve your assets. To enable this functionality you need to go into config/application.rb and add this line:
config.serve_static_assets = true
production.rb
config.serve_static_files = true
config.assets.compile = true
Command Line
bundle install
bundle exec rake assets:precompile RAILS_ENV=production
Make sure the images are in the /public folder.
Reference here

Rails asset pipeline: images not looking up resource with build id

I'm getting a 404 on all of the images included with jquery-ui-rails on Rails 4.0.1 after going production. It works fine in development environment. The site is looking for /assets/jquery-ui/ui-icons_222222_256x240.png, but only public/assets/jquery-ui/ui-icons_222222_256x240-890385424135de1513f00cbecfb7f990.png exists in the filesystem. How come production build IDs are not being appended?
I've also had this problem with some fonts. For the time being I've worked around it by just manually copying and pasting to the sought path.
First thing to try is precompiling assets specifically for the production environment:
RAILS_ENV=production rake assets:precompile
If that doesn't do anything, set the following in production.rb and precompile again
config.assets.precompile += ['*.js', '*.css']
config.assets.compile = true

Rails Assets Precompile just not working

I've pushed a Rails app to Heroku and keep on running into the following problem:
I'll save changes to my main css.scss file (in assets/stylesheets) or to images in assets/images, push to git, push that to heroku, and reload the page, only to find out that these assets haven't been loaded at all.
This was also a slight problem on the local server, but entering:
rake assets:precompile
and reloading the local server usually worked, whereas doing
heroku run rake assets:precompile
and then re-pushing does nothing. I've fished around for info and haven't found anything particularly helpful.
Of note, in my config/application.rb (some of these the result of said fishing around):
# Enable the asset pipeline
config.assets.enabled = true
if defined?(Bundler)
# If you precompile assets before deploying to production, use this line
Bundler.require(*Rails.groups(:assets => %w(development test)))
# If you want your assets lazily compiled in production, use this line
# Bundler.require(:default, :assets, Rails.env)
end
in config/environments/production.rb:
# 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
# Fallback to assets pipeline if a precompiled asset is missed
config.assets.compile = true
# Generate digests for assets URLs
config.assets.digest = true
Of additional possible interest, when I push to heroku, it says, among other things, this:
Preparing app for Rails asset pipeline
Detected manifest.yml, assuming assets were compiled locally
-----> Rails plugin injection
Injecting rails_log_stdout
Injecting rails3_serve_static_assets
and
Installing dependencies using Bundler version 1.3.0.pre.5
Running: bundle install --without development:test --path vendor/bundle --binstubs vendor/bundle/bin --deployment
I learned with Rails 3 and don't really know how the assets pipeline differs from what was available in previous version, so sorry if I'm being an idiot and putting overlapping and/or contradictory settings in my config files.
Would appreciate any help. This has been a headache.
It looks like it could be that you are add your locally compiled assets to git and pushing them and as a result Heroku is not compiling your assets on push. Check to make sure you are not adding the public/assets directory to git.

How to avoid precompiled assets being served in development mode?

I prefer not to concatenate JavaScript files in development mode, but serve them as individual files. So I configured:
development.rb:
config.assets.compress = false
config.assets.debug = true
config.assets.compile = true
In my /app/assets/javascript directory I have:
reviews.js
reviews/
foo.js
bar.js
reviews.js:
//= require jquery
//= require jquery_ujs
//= require_tree ./reviews
I include the JavaScript using <%= javascript_include_tag "reviews" %> in my layout. The generated page correctly references the three scripts individually and reviews.js is essentially empty. So far so good.
Now when I precompile my assets for production using rake assets:precompile the three JavaScript files are concatenated into reviews.js. This is all fine for production but now, in development mode, the concatenated reviews.js is served in addition to the two individual files.
Of course, this leads to all kinds of nasty bugs when developing because now, the content of foo.js and bar.js is served twice, one of them in a potentially older version in reviews.js.
How can I make sure Rails doesn't use the precompiled assets in development mode?
In config/environments/development.rb set:
config.assets.prefix = "/assets_dev"
so that in development mode Rails will look there (but it will not find anything, as you will not compile assets in development (this is indeed what you are trying to do -- not compile assets)).
When precompiling for production, use
RAILS_ENV=production rake assets:precompile
so it compiles into the default assets folder, public/assets.
It sounds like you are precompiling locally. Because the files exist in the expected location they are being served by your dev server, and the requests are not going to Sprockets.
The only way to stop this is delete the compiled files.
Normally you do not need to compile locally. It is expected that in almost all cases the precompile task will be run during deployment of the app. There is a Capistrano recipe for this on the asset pipeline guide page.
If you do need to have those files locally committed to your repo you could use a branch to avoid the problem. Reserve your master branch for production code, and make a second branch for dev. Only compile and commit assets on master. When you switch to dev, they will be gone. Merge dev into master as required.
Edit: Make sure you force your browser to update (control + F5) or you may find the old assets used from the browser cache!
in config/environments/development.rb set:
config.serve_static_assets = false
and no files from /public will be served
I tried this and it worked. rake assets:precompile RAILS_ENV=production
I observed that the new version of assets pipeline does this when you run rake assets:precompile does rake assets:precompile:all

Resources