I'm in the process of upgrading a 3.0 Rails App to 3.1.4 including the Asset Pipeline.
I'm on Heroku, so I'm I have this in my application.rb
config.assets.initialize_on_precompile = false
I noticed that when I run:
bundle exec rake assets:precompile
it creates files in a public/assets directory (even though my assets are in app/assets already).
For example, it creates files like application-72b2779565ba79101724d7356ce7d2ee, as well as replicating the images I have in app/assets.
My questions are:
(1) should be uploading these files to my production server?
(2) if I'm suppose to be uploading these, am I suppose to update each application-xxxxxxxx or only the latest one?
To your first question: Heroku will not allow you to modify the filesystem. So your assertion is correct- You will need to pre-compile the asset pipeline before you send it up to Heroku, so that it can be utilized in your production environment.
And the latter: You'll want to make sure you have the latest compilation. Any others wont be used. The "xxxxxxx" portion is to make sure that your users have the latest and greatest version of your assets. It's a way of versioning what the browser gets, and making sure they're not caching a bad copy of the JavaScript, when you want to set up their cache to hold on to the JS and CSS files as long as they can, instead of constantly getting it from your web server.
Take my Heroku comments with a slight grain of salt, as I have not deployed to Heroku before. I just know how their system works to some degree.
Related
Our release bundles are kinda huge (~50MB) and the clients take approx. 1-2 mins to download the update from codepush.
We're mostly just updating the js bundles, is there a way to just delta update the js bundle without re-downloading all image assets?
I've read from here that the server performs files diff, but it doesn't seem to work on my case: Logging RemotePackage.packageSize from checkForUpdate on clients shows the exact size of JS bundle + image assets, despite the fact that I've only changed the JS code.
Is there something I can do about this?
The CodePush backend should only serve the full contents up to the point it finishes creating a diff zip. On the backend your package is downloaded, extracted and analyzed for files that are different. Any new/updated/removed files are reconciled, put into another zip and shipped back up to the backend so users get served that instead of the original one you release. If you are seeing the full download, it's either because the backend is still working to process the diffs or there are differences inside your bundle.
I would try to do a release, wait 10 minutes and check to see if it is still downloading the full bundle. If it does, it'd be best to contact support for a deeper dive. As far as I can tell bundle's are processing correctly with next to no errors and running a quick test myself produced the correct results for me.
I had the following problem with the asset pipeline.
I have an HTML email with an image inside.
I have tests covering the case in which the email is sent successfully.
All tests pass.
When going to production, the feature requiring the email to be sent is broken, because the HTML layout is referencing a non existent image.
This obviously applies to all precompiled assets.
It seems to me that suddenly tests are no longer reliable. Is there any way to avoid this situation to happen again?
I found the perfect solution form my own case. If you set
config.assets.compile = false
config.assets.digest = true
in test environment, your tests will rely on precompiled assets.
Since it is annoying to precompile assets every time during quick development and testing phases, in my case it's enough to have this configuration on CI only.
You can setup an initializer called ci_config.rb with the following:
if ENV['CI']
class YourApp::Application
config.assets.compile = false
config.assets.digest = true
end
end
And configure you CI to run rake assets:precompile on start and rake assets:clean on end.
Compare the default configuration options in application.rb, production.rb and development.rb, and read Configuring Rails Applications in Ruby on Rails Guide to learn options.
Important options are, followings:
config.serve_static_assets: set this to false (production default), then, rails will not serve static contents.
config.assets.compile: whether compile assets using asset pipeline to compile if needed.
If you set above two options to false (that's the default for production), then you need to 1) precompile and place static contents at proper places, 2) configure web server (apache or nginx, may be) to serve static contents as needed.
So, for production, you need not only place the files, but also configure web server to serve them OR you can configure serve_static_assets to create assets on-the-fly. You may need to adjust test configuration but for test serve_static_assets is true unless you change it.
Currently it seems Heroku is determined to pre-compile assets when I push my code up to my instances.
This is great for production servers, however for my "RAILS_ENV=development" server, this causes issues, as I now get pages with all the JavaScript files served up individually from my asset manifest, and then another file with the same code all grouped up as the pre-compiled asset.
This cause my jquery datatables libraries to break, throwing popup errors, which I don't get on my local environment (development or production) or in my production Heroku instance.
Is there anyway to disable pre-compilation of assets on Heroku for development mode instances ? Or is there any reason why these aren't already disabled on development Heroku servers already ?
If Heroku detect a public/assets/manifest.yml file then they will not attempt to precompile your assets and assume you are dealing with them yourself. More details at http://devcenter.heroku.com/articles/rails31_heroku_cedar
AFAIK, Heroku has to precompile assets to work around their readonly FS and the fact that the Rails asset pipeline wants to write files to the FS. The only thing I could suggest would be to work out why your assets are breaking when being compiled.
I worked around this by adding some voodoo to my Rakefile to disable the assets:precompile rake task.
first I add the user-env-compile labs component
heroku labs:enable user-env-compile
then add this to the beginning of my Rakefile
# found from http://blog.jayfields.com/2008/02/rake-task-overwriting.html
# used by conditional heroku asset compile magick
class Rake::Task
def overwrite(&block)
#actions.clear
enhance(&block)
end
end
Then I add this rake task in lib/tasks/disable_assets_on_heroku.rake
if ENV['RAILS_ENV'] == 'development'
namespace :assets do
task(:precompile).overwrite do
puts "Asset precompile skipped in #{ENV['RAILS_ENV']}"
end
end
end
I am running rails 3.0.1, and while we intend to move to 3.1 and the asset pipeline I am looking for solutions/workarounds for asset generation during unicorn hot restarts.
Essentially what happens currently is we deploy to our site and when the deploy is complete the "current" symlink is changed to the new directory which does not have the static assets yet. Then approximately 60 seconds later all assets are generated and all is well, but for the 60 seconds before the assets are generated our site is basically down.
Questions:
If I copy the files from the old release dir, to the new dir will the asset generation overwrite the older files I've copied?
Where in the rails code is the asset generation done? ActionPack Dispatcher?
Is the generation of these assets done upon initialization of the app or at another stage?
If you layout is something like this:
/srv/yourapplication/current
You should have a shared folder
/srv/yourapplication/shared/assets
and symlink public/assets to /srv/yourapplication/shared/assets
This way each time your old assets and new assets will all be in the same folder and will be served properly.
Rails 3.1 loads pages terribly slow in development. It's processing them through the pipeline, one at a time, and takes way too long.
Is it possible to precompile my assets (which I'm not testing right now, so static files are fine) and have Rails not be responsible for serving them? Would that make things faster?
Update: Got a solution.
Richard Hulse has the correct answer to this question. rake assets:precompile will prebuild assets so they are served directly, without the asset pipeline.
But Frexuz's answer solves the problem of slow loading I've been having. Loading the Rails-dev-tweaks gem makes page loading in development markedly faster.
I had the same problem! It could take from 2-4 seconds extra to load a page because of the assets.
Take a look here (a gem): Rails 3.1 is very slow in development-mode because of assets, what to do?
This made serving assets almost instant (server console says 1ms per asset), using the asset pipeline normally.
Yes.
You can run the precompile task (in 3.1.1) and it will just work - the precompile task will give you assets without fingerprints as well as with, which is what you need in development mode. (Fingerprints are not added in dev mode).
Beware that you don't commit these to source control though.
What is more of a concern is the slowness. I have 4 stylesheets and 15 javascript files in my manifests, and it is only a bit slow on the first request.
What do you see in your logs when the assets are accessed? You should be able to see them being compiled on the first hit and each subsequent request should be a 304 not modified.
Also, do your config settings for dev match those in the asset pipeline guide? If you were compressing in dev mode with lots of files, this could be a source of slowness.