My question is similar to this one Rails 3.2 Asset Pipeline with Passenger Endless Errors except that when I try to actually go to
<link href="/assets/application-eed7996ee9017637f923133371ab3e92.css" media="all" rel="stylesheet" type="text/css" />
I get a 404. Here's the thing I don't understand. It is looking in /assets/, but when I look at the code that was deployed, the assets are only in /public/assets, which is actually a symlink to /var/www/myapp/shared/assets. So what in the world is responsible for telling the app that looking in /assets will produce correct results??
I am using Rails 3.2.0, ruby-1.9.3-p125, deploying to Ubuntu, Apache, and Thin.
I should clarify: My assets are indeed deployed to the server. Everything works perfectly fine until they need to be served, in which case production.log tells me it's looking for them in /assets/application-eed7996ee9017637f923133371ab3e92.css, which 404's.
For every request my thin.log says
cache: [GET /] miss
and production.log says
ActionController::RoutingError (No route matches [GET] "/assets/application-abecf2e096af9ee80697fd49e79a55e7.js"):
UPDATE
#Brandan thanks for the help. My assets are indeed in RAILS_ROOT/public/assets. I put this in my Apache vhost file:
DocumentRoot /var/rails/myappname/current/public
RewriteEngine On
XSendFile On
XSendFilePath /var/rails/myappname #not even sure if this line is needed
<LocationMatch "^/assets/.*$">
Header unset ETag
FileETag None
ExpiresActive On
ExpiresDefault "access plus 1 year"
</LocationMatch>
My RAILS_ROOT/config/environments/production.rb settings:
config.cache_classes = true
config.consider_all_requests_local = false
config.action_controller.perform_caching = true
config.serve_static_assets = false
config.assets.compress = true
config.assets.compile = false
config.assets.digest = true
config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache
Delete the following lines from your Apache configuration.
ProxyPass / balancer://thinservers/
ProxyPassReverse / balancer://thinservers/
The answer came from In Rails, should I enable serve_static_assets?.
Typically, your assets should only exist in /public/assets for a deployed application.
Apache should be configured so that its DocumentRoot is your RAILS_ROOT/public. Then it will serve http://example.com/assets/whatever.css from RAILS_ROOT/public/assets/whatever.css, and it never goes through Rails for static assets.
Have you restarted your application since you precompiled your assets? Sometimes Rails is expecting an older/newer compiled version of your assets than is currently deployed.
I've been having this problem for days now. Thought it was an issue with capistrano or the ruby version however I'm pretty sure it's permissions related too.
My configuration was pretty much the same as yours although I'm also using Unicorn.
Here's what I did to sort:
Temporarily remove the following section because I think that was causing problems with the troubleshooting:
<LocationMatch "^/assets/.*$">
Header unset ETag
FileETag None
ExpiresActive On
ExpiresDefault "access plus 1 year"
</LocationMatch>
Perhaps get it all working and then add it back in. I don't think it's the cause of the problems however, when diagnosing things like this, it's best to remove as much as you can to find the culprit.
Run a chown -R xxx.xxx (replace xxx with your application user or web user) on the public directory. As soon as I did so, the css appeared again.
(What I did but maybe not essential) You might also want to install locally without cap. just in case there's an issue with it. That also worked for me.
Completely wipeout tmp/cache and public/* just in case.
Restart your apache server a couple of times.
You can see a gist of my conf. here
Try removing the ProxyPass and ProxyPassReverse directives from your apache/thin configuration. The P flag in your rewrite rule is already performing the proxy pass that you desire.
See http://httpd.apache.org/docs/2.0/mod/mod_proxy.html for more information.
Passanger knows its a RoR application as there is a config.ru file.
The same error you are reporting happened to me due to wrong permissions. Apache was not able to serve the files inside assets, but was able to send the files on public/
In my case I use capistrano so assets was a symlink to shared/public/assets.
what I did was:
chmod -R o+x shared/
x permissions are required to list and access directories. After that it worked. You have to make sure that assets has +x for others
Related
I want to show unbundled javascript and css of my web-application to a UI developer. I have tried adding require 'sprockets/railties'
config.assets.debug = true
in my production.rb, but it did not work and I can still see bundled, uglified css/js in my browser sources.
I tried running my production in development mode by adding rack_env development in my /etc/nginx/nginx.conf http block, but I get Bad Request due to following error:-
invalid number of arguments in "rack_env" directive in /etc/nginx/nginx.conf:16
Please help
Did you try purging and recompiling your assets by any chance? Depending on your deploy method, production assets may not be recompiled on every deploy / application start.
rake assets:clean (rake assets:clobber) for Rails 4+
rake assets:precompile
By default, config.assets.debug = true is what controls this 'bundling' behavior.
You might also try to comment out
config.assets.js_compressor = ... or
config.assets.css_compressor = ...
if you have any of those in your production.rb.
Another reason may be any sort of external cache, depending on where you host your app: Cloudflare or Heroku Asset Pipeline Cache (those usually cache based on MD5 of your assets).
And the last but not the least is... browser cache, just in case :)
I have to precompile assets locally in order for one of my JS plugins to work correctly.
Whenever I make a change to any asset and precompile, I get a new version in public/assets, and the old one is there, too. When I run locally in production mode, I am served a page with the new assets.
When I deploy to EB, the pages always contain links to the old assets.
Of course, application.html.erb uses the dynamic css link tag: <%= stylesheet_link_tag "application", media: "all" %>
production.rb contains:
config.action_controller.perform_caching = true
config.assets.compile = true
I think this must have something to do with Nginx or some sort of caching in EC2 on the html files because puma runs locally.
I have tried:
Different browser, PC, cleared cache, disable cache. It is not the browser.
Setting send file off in nginx.conf.
Setting cache expiration to -1 for html and confirmed with curl that I receive Cache-Control: no-cache
Renamed entire app/current folder. I still receive a page, but it is missing the CSS. Where are the files that are actually used after a server is started?
rake tmp:clear on the server.
Looking all over the server for any nginx or puma cache. I found nothing.
Researching for hours on end over the past 2 years.
The only thing that ever works is to rake assets:clobber, create a new EB environment, and deploy a few times. Sometimes, even that doesn't work.
Please help!
After additional countless hours of failing to solve this, I noticed a variable in the Elastic Beanstalk configuration settings that I had been changing from the default value. RAILS_SKIP_ASSET_COMPILATION - I was setting it to true since I was trying to manage the asset compilation myself. Flipping this back to false fixed my issue and significantly increased my deployment time. My third-party javascripts and gems all work correctly as well.
I still think this is a workaround because I should be able to precompile manually. However, it is good enough for me at this time.
I had a similar issue with caching assets on staging or production server. When I checked Last-Modified attribute of an asset file, for example with curl -I http://url-to-the-asset-file server returned old (cached) file.
What solve the issue was updating assets version in production.rb file. It will force assets to recompile with new MD5 hash fingerprint.
# config/environments/production.rb
# Version of your assets, change this if you want to expire all your assets.
config.assets.version = '1.1'
Hopefully this will help you or at least give some guidance.
I'm trying to configure my apache server for serving static assets from my rails app. I already tried the suggested configurations but my assets still aren't shown and when trying to access them directly I just got an rails error that no matching controller was found but the asset stuff should be handled by apache directly I think.
My apache configuration looks like this:
<VirtualHost *:80>
ServerName xxx
DocumentRoot /home/xxx/test/public
PassengerEnabled off
<LocationMatch "^/assets/.*$">
Header unset ETag
FileETag None
ExpiresActive On
ExpiresDefault "access plus 1 year"
</LocationMatch>
ProxyPass / http://127.0.0.1:9292/
ProxyPassReverse / http://127.0.0.1:9292/
</VirtualHost>
Did I missed something?
I used,
RAILS_ENV=production bundle exec rake assets:precompile
To make it all work right, I added this to config/application.rb...
module MyApp
class Application < Rails::Application
.
.
config.assets.precompile += ['custom.css']
config.assets.precompile += %w(*.png *.jpg *.jpeg *.gif)
.
.
end
end
(I had created custom.css.scss. But Rails did not recognize .scss, as you see above.) I assume that all your assets are appearing in public/assets folder after precompile. I don't understand what you are doing with LocationMatch, pardon my ignorance. Further more, I did not use port 80. I used 8000. Not sure if that makes a difference.
Also, there's a setting in config/environments/production.rb,
# Disable Rails's static asset server (Apache or nginx will already do this).
config.serve_static_assets = false
This is directly from the Rails Asset-pipeline documentation regarding the Apache server:
http://guides.rubyonrails.org/asset_pipeline.html
4.1.1 Far-future Expires Header
Precompiled assets exist on the file system and are served directly by your web server. They do not have far-future headers by default, so to get the benefit of fingerprinting you'll have to update your server configuration to add those headers.
For Apache:
# The Expires* directives requires the Apache module
# `mod_expires` to be enabled.
<Location /assets/>
# Use of ETag is discouraged when Last-Modified is present
Header unset ETag
FileETag None
# RFC says only cache for 1 year
ExpiresActive On
ExpiresDefault "access plus 1 year"
</Location>
So I started investigating the asset pipeline in Rails3 and I have a desired use case that is somewhat off the beaten path... so I'm looking for a recipe.
I often run webrick locally for development and then run
Passenger+Apache for deployed instances of the app.
the app is configured with a suburi path, e.g. http:// server/approot/...
to make webrick paths work like deployed instances, I added map '/approot' do run app to config.ru. Now webrick is also at http:// local:3000/approot/...
The Confusion
Given this setup, I tried to use rake assets:precompile and have been having a lot of configuration problems between local, deployed -- missing files, incorrect paths, 404s in firebug, etc. Here's a smattering of solutions I've tried:
config.assets.initialize_on_precompile = false to application.rb to prevent trying to initialize the app for production, (we have several deployed environments and call them different names, ug.) when precompiling the assets.
config.assets.precompile += %w( *.js *.css ) to application.rb to include things like jquery.js and ujs and rails.js that were missing.
config.assets.prefix = "/approot/assets" to correct a problem where the map above (in config.ru) doesn't apply to assets, so assets had to be precompiled to ./public/approot/assets, but I'm not sure if that only works locally, i.e. if I deploy, will my asset paths be http:// server/approot/approot/(js|css|...)?
When precompiling assets, the rake task switches to env production, but then it is unclear from the Rails3 doc whether sprockets continues to compile on the fly locally and use those dynamic assets, or whether it will serve the static precompiled assets instead?
I tried putting config.serve_static_assets = true in environments/development.rb, but I'm not sure how this works with config.assets.compress = false and config.assets.debug = true. Setting the assets.debug to false just seems to hide the GET requests in the webrick log, although I saw a post saying that "solved the problem" [sic].
Requirments for a Recipe
So I'd like a recipe that does the following:
assets are consistently and correctly served from a path http://server/approot/assets/... whether run in passenger or webrick (i.e. deployed or local). If this isn't possible, then I can switch my local dev environment to use Passenger+Apache as well, it's not a big deal, but I just want to know if it's possible.
raw assets exist in /app/assets like normal Rails3, but when I precompile them, they work exactly the same way in deployed envs so that asset file references don't break (i.e. right now, there are a lot of refs looking for /assets/image/... when the path is clearly set up as /approot/assets/image.... (It's unclear from the Rails3 doc whether there are assumptions about deploying to root vs a suburi, e.g. http:// server/assets/... vs. http:// server/approot/assets/...)
sprockets can't be used in deployed environments (our restriction, sorry). So this means the rails3 app has to effectively look like a static asset app. I know this is what precompiled assets are supposed to do, but the pathing issues are preventing me from getting this working as advertised.
TL;DR - I feel like I'm trying a lot of separate things that might work if I only knew the right combination of them.
References
http://guides.rubyonrails.org/asset_pipeline.html#precompiling-assets
http://blog.55minutes.com/2012/02/untangling-the-rails-asset-pipeline-part-2-production/
http://blog.55minutes.com/2012/02/untangling-the-rails-asset-pipeline-part-3-configuration/
https://github.com/rails/rails/pull/3946
Ok, here's a potentially horrible answer, but it seems to work with webrick in two contexts now and it's the day after Halloween (although I haven't tried this approach in deployed slots yet).
Configuration
Unless otherwise mentioned, everything is defaults from a rails new app generation.
config/application.rb
config.assets.initialize_on_precompile = false
environments/production.rb (not really production, only used for rake asset:precompile)
config.assets.css_compressor = :yui
config.assets.js_compressor = :uglifier
environments/stage.rb (this is one of our deployed envs)
config.serve_static_assets = true
config.ru
This is the horrible part. I duplicated the map so that Rack would serve both the suburi and the root. So the controller action that shows the layout can have http:// server/approot/foo/index, while the assets within the layout can be loaded from http:// server/assets/...
map '/approot' do
run AppRoot::Application
end
map '/' do
run AppRoot::Application
end
Running it locally
$ rake assets:precompile
$ rails s
and in firebug I see the separate parts served by sprockets (all 200 OK):
GET /approot/
GET /assets/application.css?body=1
GET /assets/jquery.js?body=1
GET /assets/jquery.ujs.js?body=1
GET /assets/application.js?body=1
Ok, so now test a 'deployed' slot locally and see if the compiled assets work?
$ rails s -e stage
and then I see the correct precompiled assets (all 200 OK):
GET /approot/
GET /assets/application-xxxxxxxxxxxxxxx.css
GET /assets/application-xxxxxxxxxxxxxxx.js
Ok, so this isn't as nice as a real suburi solution and I think I'm going to have problems in deployed slots. Round 2, fight!
I'm trying to get Redmine (a Ruby on Rails app) working. It works fine when started with ruby script/server webrick -e production, however, I'm having trouble getting it working in Apache with Passenger.
Accessing http://example.com/redmine returns the Redmine home page, but clicking any link (or even adding a / to the URL) results in a 404. According to the Rails log, a RoutingError occurs. For example, when opening the projects page: ActionController::RoutingError (No route matches "/projects.html" with {:method=>:get})
The Redmine directory is /var/www/localhost/htapps/redmine. I followed the documentation at http://www.modrails.org/documentation/Users%20guide.html#_deploying_a_ruby_on_rails_application (section 3.2), so there's a symlink at /var/www/localhost/htdocs/redmine pointing to ../htapps/redmine/public, and the Apache configuration contains DocumentRoot /var/www/localhost/htdocs and RailsBaseURI /redmine.
What is causing it to raise these RoutingErrors?
It looks like this issue was actually caused by the default .htaccess included with Redmine.
Redmine's .htaccess rewrites every request to end with .html. Redmine's routes expect .html-less requests.
Setting RewriteEngine to Off solved the issue for me.
http://ptspts.blogspot.com/2009/05/how-to-fix-railsbaseuri-sub-uri-with.html
The manual workaround (according to what is suggested on the pages above) is adding the line below to config/environments/production.rb:
config.action_controller.relative_url_root = '/redmine'
If not deploying to a Sub-URI and deploying using passenger, adding the rule RewriteRule ^(.*)$ dispatch.fcgi [QSA,L] to your public/.htaccess also solves the issue. As that rule is IfModule-ed out in the default .htaccess.
Another option is to delete .htaccess if you're not using it (As an example you may be using it for additional layer authentication with AuthType Digest etc). It is not required when deploying with passenger.
Even if you will manage to run Redmine in suburi, redmine still will have issues.
Some pages won't be parsed and displayed correctly, if displayed at all.
This issue is almost one year old and indicated for next minor release. Btw dozen minor releases came out, but it's not yet fixed. FCGI mode does not support sub-URI.