I am developing with Rails 3.2.8.
One annoying thing is that if an image is missing by mistake, it gives an error in production mode.
Let's say that I put the following code.
And actually I forget to place my.jpg file in app/assets/images, it's ok in development (browser will just ignore the missing image) but it gives a rails error in production mode.
How can I find the missing files before deployment?
Thanks.
Sam
What I do when building a new release for a deploy is set the following in my config/environments/test.rb
config.assets.compile = false
config.assets.digest = true
This mimics the production environment config for the asset pipeline, preventing the assets from being compiled and forcing the lookups through the manifest.yml files/asset pipeline. Run your tests (you do have tests, right? :-) ) and watch for a failure.
If you don't have tests, grep you log/development.log for a 500 error
tail -f log/development.log | grep 500
Go through a few pages manually and watch for new log entries appearing in the tail. You should look into writing tests to automate this though.
The reason you're seeing the errors in production is because the asset pipeline can't find the assets you're requesting and raises exceptions due to this. In development things are more lenient so that debug info can be presented to you in favor of the 500 errors. By changing the above config in your environment, you're telling rails to act strictly with respect to it's response to missing assets through the asset pipeline, allowing you to catch the problem before it makes it's way to production.
You can watch the rails console running in dev mode... it shows a warning when it can't find the image.
Also, use the browser's error console. Both of those will tell you what's missing and then you just start grepping or visually searching to see where you did (or didn't) put the image.
I don't know why it would be annoying that the production server is less kind to the broken code than when you were in development unless you actually want to roll out code with missing objects and references.
Related
When I run assets:precompile on my server i can clearly see that my assets are getting precompiled, also files are being written to filesystem properly, but when I visit my application from browser I am getting not found error because asset file names that are being referenced in HTML are older ones.
I am absolutely clueless about how to debug this issue. Any kind of refrence/help will be highly appreciated
Based on OP's comments, the app is in production environment and as such, it needed to be restarted to force the app to reevaluate the asset hashes.
After following this tutorial, I tried was able to set up a rails application on an ec2 Ubuntu instance, running nginx web server and puma app server, deployed with capistrano 3. However, none of my assets are showing up, and I'm getting routing errors for basic functions of the Devise gem such as logging out. The chrome dev tool console shows 404 errors for the compiled application.css and application.js files.
I think the assets are there because if I ssh into the instance and go to the folder where my app is, I can see a bunch of files under public/assets. Also, if I check the capistrano logs, I can find the line bundle exec rake assets:precompile, and the status for that is successful. I tried things like going into the production.rb file and changing config.serve_static_files = ENV['RAILS_SERVE_STATIC_FILES'].present? to config.serve_static_files = true
but still no assets. I think the biggest suspect is that there is some sort of routing error, because I don't really understand how web servers, app servers, and aws instances interact with each other. Could anyone point me in the right direction on debugging this? If you need to see a specific config file please comment below.
Ok it turns out all I had to do is copy the secrets.yml from the local repo for my app to the shared folder that is in [my_app_name]/shared/config. So my app didn't know where to look for the secret key base.
Although I'm still confused on why not having the secret.yml would prevent assets from served...
I'm having a real tough time diagnosing a 500 error from my application running in production. I've had it working before, but after re-deploying via Capastrano I am unable to get it going.
Here are the facts:
The server is setup with nginx + passenger, and I'm using
PostgreSQL.
Static assets are working properly, as in I'm able to access them just fine in a browser.
I can access the rails console via RAILS_ENV=production bundle exec rails console and perform Active Record actions (like
retrieving data from the db).
Within console, I can run app.get("/"), which returns a 500 error as well (after first showing the query that was run to load
the model).
The production.log file is never written to. I've set permissions 777 on it just for the hell of it. I've also set the log level to
:debug with nothing to show for it.
The nginx log (which passenger also uses) shows no indication of errors, it just notifies about cache misses.
Because nothing of use is being logged, I have no idea what to do here. I've tried setting full permission on the entire app directory with no help. Restarted the server multiple times, nothing. The database is there and rails can clearly communicate with it. I'm not sure what I did to get it to run the first time around. I just don't know why rails isn't outputting anything to the log.
Okay, I figured this out. The app ran fine in development mode, so I knew something production-specific was screwing it up. I went into config/environments/production.rb and changes these settings:
# Full error reports are disabled and caching is turned on
config.consider_all_requests_local = false # changed from true
config.action_controller.perform_caching = true # changed from false
And then after restarting passenger, rails showed me the error w/ stacktrace. Turns out I was forgetting to precompile the asset pipeline!
Things to check
1) Are you sure you are running in production environment?
Check to see if any entries are in the development.log file
2) Set up your app to email you when a 500 error occurs with a full stack trace. I use the Exception Notifier gem but there are plenty of other solutions for this.
3) When checking your app in the console are you sure you are starting the console in production mode? It is possible that the app is not starting up at all and you just forgot to set the production param thereby thinking that the app runs fine when it doesn't.
4) Are you getting an nginx 500 error or the Rails 500 error? If nginx then it is likely that your app is not starting at all and highly unlikely that you will get any rails error in your log file. The assets are static files and navigating to them proves nothing other than that they exist.
5) Are you sure you are checking the right folder on the server? Sounds really stupid but capistrano could be deploying the app to a folder that is different to the folder that nginx is looking for for your app so double check both the folder capistrano is deploying to and the folder that nginx is looking for are the same.
Just a suggestion, I would use puma rather than passenger. It's awesome with nginx.
My problem is passenger's log file (error.log) has nothing. Then it's a rotation log issue. Run
passenger-config reopen-logs
solved my problem. More.
Have you tried running in development mode to see if the error reports itself?
The problem in a nutshell is that in development mode we'd make changes to CSS or JS files but would always get cached/old versions of these files. Nothing I did had any effect. I checked configuration dozens of times and tried every combination of config values but always kept getting the same results: stale/cached files. I had to actually run in production mode and restart the server after every change to test.
I spent days tearing my hair out over this issue, looked at dozens of stackoverflow questions on the asset pipeline but never found one that addressed it so I thought I'd post it here for posterity.
We use Heroku and precompile our assets because Heroku fails to precompile for us (we also use devise which apparently is the cause of the heroku precompilation failure). So in order to push our precompiled assets up to Heroku we have to check them in to git.
Here's the problem.
When we upgraded to Rails 3.1.1 asset precompilation produced files both with and without the MD5 hash in the name. I didn't think much of this and went ahead and checked all these files in so I could push to heroku. Sometime later I noticed the problem with cached results in development mode. The precompiled and checked in assets without the MD5 hashes were being served from /public/assets as static files which prevented us from seeing any changes we were making in /app/assets.
After finally realizing this I ran git rm /public/assets and everything works again. So the takeaway is: Be careful checking assets into git!
To turn this into a question: how do others do this? Am I missing something obvious? What I'd really like is for Heroku to precompile my assets for me but it is failing with a db connection error that I gather is because of devise. I had hoped Rails 3.1.1 fixed this but it didn't.
Have you checked out this devise issue on github? Specifically Jose Valim says
Rails 3.1.1 final has a method called
config.assets.initialize_on_precompile. If you set it to false, you
should be good but it won't allow you to access model information on
your assets (which you probably shouldn't anyway).
Maybe this will allow the precompile to happen on Heroku for you.
The reason the asset precompilation does not work could well be, that the Heroku ENV vars are not present on slug compilation (deploy) as stated here:
http://devcenter.heroku.com/articles/rails31_heroku_cedar
There is an (experimental) way to enable the ENV vars during deploy for exactly this reason, find information here:
http://devcenter.heroku.com/articles/labs-user-env-compile
Hope this helps.
Check this guide from Heroku. It outlines the 3 ways to deploy Rails 3.1 apps. Two of these do not required local precompilation.
I'm just getting acquainted with Rails 3.1, and I burned some time updating an old project and trying to work out how the new asset pipeline behaves in development mode versus production.
The default config.assets.precompile setting blesses only application.css and application.js, with the intention that everything should be served as a single stylesheet and a single javascript file.
Obviously there are situations when we don't want that, so we can add items to the list in that config variable...
Here's the situation I ran into with my sandbox project when going to production:
Browsed the site in development, saw that everything was working. The assets were linked as separate files and the site displayed correctly.
Uploaded the site to my server, and tried to get it working in production. The first error was saying that "ie.css" (a conditional stylesheet) isn't precompiled. (I was in Safari and this stylesheet wouldn't even be downloaded: the error was raised from the stylesheet_link_tag helper before rendering the page.)
Ran rake assets:precompile and tried again.
Added the offending item to config.assets.precompile and tried again.
Kicked the error down the curb until it hit another asset error.
GOTO 3.
Not knowing how to address this, I went around in circles a few times until I thought I got all the assets and the site was rendering in production. Then I tried it in MSIE and hit another error 500: "belated_png_fix.js" was being conditionally loaded, and it didn't crop up until then.
So my question is, other than trial and error or a heavy dependence on integration testing, how can I predict that my site isn't going to bomb out when the asset pipeline discovers that some stylesheet or javascript wasn't added to the precompile list?
I'm also curious why a missing stylesheet asset should cause the whole page to error 500 instead of just compiling it on-demand or serving a 404 when that asset is requested. Is this a deliberate design to "fail early"?
I've just released a gem called assets_precompile_enforcer, which ensures that developers won't forget to add assets to config.assets.precompile while they are developing. An exception will be raised if you include an asset via javascript_include_tag or stylesheet_link_tag, and it doesn't match a filter in config.assets.precompile.
This means that asset errors will be caught during development, instead of being discovered after deploying to production.
I had similar problems with rails 3.1 as well. The best thing you could do is to install capistrano multi stage and get a staging server.
If for any reasons this is not possible, install a virtual machine on your computer and try to replicate your servers environment.
Continuous deployment is a great thing, and you should get to the point where it is so simple that it really isn't that painful anyway. That being said, config.assets.precompile can take regexs, so how about you come up with a standard for top level sprockets "manifest" files, or a standard sub folder for things that will not be bundled up? (note that I haven't actually tried this yet...)
This may be overkill, but this works for me (it gives me clean, compiled assets). I have this in my .bash_profile file.
alias ggo='bundle exec rake assets:clean && bundle exec rake assets:precompile && git add . && git commit -m "precompile" && git push origin master && cap deploy'
and this in my config/environments/production.rb (forces production to compile when needed; shouldn't be a need to if I remember to run "ggo" first):
config.assets.compile = true
So, my workflow is:
1. code
2. git add & git commit
3. if I touched CSS/SASS/JS/CoffeeScript files, I run ggo. Otherwise, I do a normal cap deploy.