Using Rails 6.0.2.1 with Ruby 2.6.3 and NGINX
I have a rake task that has the job of re compiling assets when they change in the production server
#Called by delayed job UpdateAssetsJob
require 'rake'
desc "Applying Theme, will restart server and may take a while!"
task :apply_css => :environment do
Rails.logger.info("Applying CSS in #{Rails.env}")
if Rails.env == "production"
Rails.logger.info("Compiling Assets")
Rake::Task['assets:precompile'].invoke
Rake::Task['assets:precompile'].reenable
# `RAILS_ENV=production rails assets:precompile`
Rails.logger.info("Cleaning assets - busting cache")
Rake::Task['assets:clean'].invoke
Rake::Task['assets:clean'].reenable
# `RAILS_ENV="production" rake assets:clean`
Rails.logger.info("Restarting Puma server")
`bundle exec pumactl -S /home/app_path/shared/tmp/pids/puma.state -F /home/app_path/shared/puma.rb restart`
end
end
The problem with this is that assets will only ever be compiled once.
I have tried clobbering the assets before compiling using
#Clobber assets to force recompilation
Rails.logger.info("Clobber Assets")
Rake::Task['assets:clobber'].invoke
Rake::Task['assets:clobber'].reenable
But again this will only work once
The scenario is:
An administrator updates colours for the current application theme which causes a background task, delayed job, to write necessary changes to
assests/stylesheets/_colours.scss file
For these changes to take effect I compile the assets, clean the assets, ensuring visitors that have cached assets get the latest version and then restart the server
As I am using the partial syntax for the naming of _colours.scss I have no need for this functionality in the development environment as changes are automatically picked up
Suggestions for a more appropriate solution are welcome
Solved the issue by switching from using
Rake::Task['assets:precompile'].invoke
Rake::Task['assets:precompile'].reenable
to
RAILS_ENV=production rails assets:precompile
I do need to clobber the assets and unexplainably the assets:clobber task will run multiple times once I switched the precompile task
Problem solved
Related
I recently added the turbo sprockets gem https://github.com/ndbroadbent/turbo-sprockets-rails3
to my rails application, I'm using capistrano to deploy to Amazon EC2.
I'm a little confused on how I can make this work.
assets:precompile worked on my local machine, but on the amazon instance it didn't.
Long story short capistrano makes a new release directory for each deployment and the public/assets
directory is empty, so every time it creates a new one and when running assets:precompile it precompiles all of the assets.
Should I precompile localy and add them to git or copy the public/assets directory from the last deployment before capistrano runs assets:precompile?
What would be the cleanest/best practice solution?
Or should I keep the compiled assets in a shared directory?
The simplest solution I could think of is using the shared/assets directory to store
my assets and make a symbolic link to the the release public/assets directory before the assets are being compiled .
task :assets_precompile do
run "ln -s #{shared_path}/assets #{release_path}/public/assets"
run "cd #{release_path} && RAILS_ENV=production bundle exec rake assets:precompile"
end
Edit: Anjan pointed out that if you use deploy:assets ( If you have load 'deploy/assets' in your Capfile ) this is done by default so that's a cleaner solution .
Lesce's answer has greater weight if the deploy process includes symlinking to static files.
Example: config/database.yml is something you don't tweak, nor want a deploy to necessarily change on you...
Having that in shared/assets will lead to failure when assets:precompile gets called.
It also works for cases with user loaded images, attachments...
The problem with this app is that is WIP, so we are not using anything to deploy it to our production server, we just clone it from github and we are doing a git pull every time we have something done, rake assets:precompile task takes more than 30 minutes to finish!, WTF?.
We are doing this:
$ bundle exec rake assets:clean
$ bundle exec rake assets:precompile
Our production server:
ruby 1.9.3p194 (rbenv)
rails 3.2.3
unicorn
nginx
Our rails + unicorn + rbenv + init.d daemon configuration is here: https://gist.github.com/2776085
Now, here's our assets manifests, Gemfile and our production.rb files: http://pastie.org/3958070
So, somebody knows why this takes so long? or there's a way to speed up assets compilation in production?.
Thank you.
UPDATE: Assets compilation times locally: http://pastie.org/3961734
Rails's asset pipeline looks a little bit further than app/assets/{javascripts,stylesheets}.
As mentioned in the guides, there are also other locations where you can put your application's assets:
app/assets
lib/assets
vendor/assets
I suggest you to read the complete guide on Rails's asset pipeline to get more information about all this and also some tips for your production environment, such as nginx rules for caching, speeding up the assets pre-compilation, etc.
Was our fault, we have an extra folder inside app/assets, like app/assets/blah with a lot of folders inside, so the assets pipeline was looking over there, still, we don't know why the assets pipeline isn't just looking inside app/assets/javascripts and app/assets/stylesheets.
Started working on a new application this week that is running the latest rails 3.2.2 with the asset pipeline. For the assets I would like the assets to be compiled when pushing the app to heroku (rather than having to manually compile and store compiled assets in the repo). The docs suggest this should happen automatically.
The problem I have is when I run git push heroku master it does not seem to run the rake assets:precompile task at all. The assets are never compiled. Here is the output I get:
-----> Heroku receiving push
-----> Ruby/Rails app detected
-----> Installing dependencies using Bundler version 1.1.rc.7
Running: bundle install --without development:test --path vendor/bundle --binstubs bin/ --deployment
Using rake (0.9.2.2)
.......
.......
Your bundle is complete! It was installed into ./vendor/bundle
Cleaning up the bundler cache.
-----> Writing config/database.yml to read from DATABASE_URL
-----> Rails plugin injection
Injecting rails_log_stdout
Injecting rails3_serve_static_assets
-----> Discovering process types
Procfile declares types -> web
Default types for Ruby/Rails -> console, rake, worker
-----> Compiled slug size is 61.7MB
-----> Launching... done, v30
[appname] deployed to Heroku
I have the asset pipeline enabled in my application.rb
require File.expand_path('../boot', __FILE__)
require "action_controller/railtie"
require "action_mailer/railtie"
require "active_resource/railtie"
require "sprockets/railtie"
Bundler.require *Rails.groups(:assets) if defined?(Bundler)
module Appname
class Application < Rails::Application
# ...
# Enable the asset pipeline
config.assets.enabled = true
# Do not boot the app when precompiling assets
config.assets.initialize_on_precompile = false
end
end
Anyone know what might be causing the problem? I'm happy to gist more code if need be. If I run heroku info it shows that i'm running on the Cedar stack.
I had to turn on config.assets.compile = true to stop receiving 500 errors in production, although this compiles the assets at runtime (which I do not want).
This seems to be solved now. I believe it was caused by the Rakefile not loading the assets:precompile task in production.
The rakefile was loading up tasks for both the cucumber and rspec gems which are not bundled into production. As a result the assets:precompile task was not available in production so heroku didn't attempt to run it.
I wrapped the test tasks in a environment check conditional like so:
if %(development test).include?(Rails.env)
require 'rspec/core'
require 'rspec/core/rake_task'
end
If there's anything wrong in your Rakefile then the precompile step will be skipped entirely. For me, I was referring to a dependency that was only being loaded in my test and development environments and not production so the rakefile was bombing.
Using the suggestion from #Lecky-Lao worked for me.
heroku run rake -T --app staging-hawkmo
Running `rake -T` attached to terminal... up, run.1
rake aborted!
cannot load such file -- jasmine-headless-webkit
Once I saw that it was as simple as wrapping the Rakefile require in an environment test.
I normally add this to production.rb:
# Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added)
config.assets.precompile += %w( style.css grid.css ... geo.js jquery.flexslider-min.js)
and set:
config.assets.compile = false
It appears that this results from something dying because of a fatal error when heroku attempts to start/check for assets. This may not actually be related to Rails 3.2. I don't know.
I didn't have time to wait for heroku to help so I went through the painful process below to determine what the problem was. I recommend you do it also.
Create a new, separate rails 3.2.2 app. There is nothing in it besides the default files. Create a heroku app: heroku create --stack cedar. Just for your sanity, push out this app as it stands and see that the precompilation step happens during slug compilation.
Copy into the new app, each logical block of your application. I started with app/assets. (thinking it was something to do with assets and precompilation... nah) cp -R ../ProblemApp/app/assets/* app/assets/ Then add, commit, and push this to the heroku git remote.
At some point, you are going to copy over a group of files that will stop the assets:precompile message from appearing during slug compilation. Now, one by one, revert those files to the original raw state or comment out suspicious lines and push back out to heroku. Once you see the precompilation message again, you've found your problem.
It turned out that for us, I had several false alarms. When I copied the config directory over to the new app, the app module name was our old app and not the new one. This also prevented the precompilation from happening, but it was not the original cause I was looking for.
In the end, we had a rake task that was responsible for loading CSV data into the app during development. It had one line that was causing a problem:
require "#{Rails.root.to_s}/config/environment"
Commenting out this line in our original app fixed our problem. So is this Rails 3.2 related? Why is heroku running unrelated rake tasks? I dunno. But shit's working. :)
Just having the same issue on both Rails 3.1.3 and Rails 3.2.3. Following Mario's idea, The rake task do exist while I run "heroku run rake -T". So anyone got feedback from Heroku's feedback yet? I might just raise ticket for this as well then...
I had the same problem I following this guide https://devcenter.heroku.com/articles/rails-asset-pipeline fixed it.
Regards.
Try to add the following into production.rb
config.assets.precompile = ['*.js', '*.css']
I also found this site https://coderwall.com/p/ga9l-a
Rename your css to .css.erb and use the asset_path tag in your rule.
E.g.
background: url(<%= asset_path 'bg.png'%>);
As mentioned in 2.3.1
http://guides.rubyonrails.org/asset_pipeline.html#coding-links-to-assets
Could somebody explain to me what the command rake assets:clean really does? Unfortunately the Rails Guides dont mention it. There is also the command rake assets:cleanup. Whats the difference?
Furthermore could somebody tell me when do I have to run rake assets:precompile in production. Do I run it on the server console after I deployed all my application files to my production server? Or do I precompile on my local machine and then do a deploy of all files?
Thanks all
Note: This answer is rails 3 specific. For rails 4 and later, look at other answers here.
If you precompile on your local machine, then you can commit these generated assets into the repository and proceed with deployment. No need to compile them on production machine.
But it introduces a problem: now when you change source files (coffescript / scss), the app won't pick up the changes, because it will serve precompiled files instead. rake assets:clean deletes these precompiled files.
In my projects assets are precompiled as a part of deployment. Capistrano makes it very easy.
Also, I never heard of rake assets:cleanup.
Run rake assets:clobber to actually clean the assets.
http://www.dixis.com/?p=735
Sergio's answer was completely correct in Rails 3. rake assets:clean deleted all assets that had been previously precompiled into the public/assets directory.
In Rails 4, you run rake assets:clobber to do the same thing.
If you run rake assets:precompile with the following config (by default turned on in staging and production):
# config/environments/production.rb
config.assets.digest = true
You compiled assets get timestamped. This means you can compile your new assets while leaving the old assets in place. You usually want to do this in production so you website will still access the old files while your running precompile to create your new files (because you've added new css/javascript). You now want to get rid of the old files that are no longer in use. The clean it removes the old versions of the precompiled assets while leaving the new assets in place.
rake assets:clean removes compiled assets. It is run by cap deploy:assets:clean to remove compiled assets, generally from a remote server.
cap deploy:clean removes old releases, generally from a remote server. It is not rake assets:clean
rake != cap
rake assets:clean is now run by cap deploy:cleanup_assets. Add require 'capistrano/rails/assets' to your Capfile and you get this cap-task. My capistrano version is v3.2.1.
clean up those untracked files with git clean -f for files and git clean -f -d for directories
When I run "bundle exec rake -T" in development, the assets:clear and assets:precompile tasks show up, but if I prefix that command with RAILS_ENV=production, or run it on a server where that variable is set, they don't. Has anyone run into this?
I'd removed rails/all from the application.rb and replaced it with the individual railties, excluding activerecord. Turns out you also need to require the sprockets railtie.