How to change the directory public assets are served from in rails?
My setup:
thin running on port 1234 with --prefix /foobar
apache running on port 80
apache reverse proxies /foobar
to thin on port 1234
I would like the static assets to not be served via the proxy to thin, but instead be served at /assets
directly via apache instead.
I have to use a relative path because I don't know the host name/ip of the rails application before startup (it's app-in-a-box that should be able to be moved aroun开发者_如何学God).
I found config.action_controller.asset_host
in production.rb
, but I can't set that to a relative path. When I do it gets confused and creates really bogus URLs.
How can I make this work?
You don't need to call it through the config block in the environment, you can call it from the application controller, which gives you access to the request object. So you could do:
class ApplicationController < ActionController::Base
before_filter :set_asset_url
def set_asset_url
ActionController::Base.asset_host = "http://#{request.host}"
end
end
It feels a little hackish but I know of no better way.
and if you need to worry about ssl and different ports, you could go crazy:
ActionController::Base.asset_host = "http#{request.ssl? ? 's' : ''}://#{request.host_with_port}"
This depends in your server environment somewhat, but basically you want something along the lines of what is described here: http://blog.codahale.com/2006/06/19/time-for-a-grown-up-server-rails-mongrel-apache-capistrano-and-you/
First, I want to thank Geoff and darkliquid. I took what was in darkliquid's link and worked on it to make it work for my case. The big challenge was that I wasn't serving the rails application from the root of the webserver.
Notes:
thin
is run with--prefix '/railsapp'
on port 9999.- This works for windows and linux. W00T!
- I have to use the
LA-U
(look-ahead) to get the final filename apache would use. - The
IS_SUBREQ
check is to prevent the look-ahead (a sub request) from ever returning the proxy. - The
/railsapp/index.html
rewrite is required because otherwise another rule in my apache conf would rewrite it to/index.html
, which is a default 'here's what's here' page;404
s are served elsewhere, though.
Here's the relevant part of the apache configuration:
# Only proxy the thin stuff.
<Proxy /railsapp/*>
Order deny,allow
Allow from all
</Proxy>
## Add an alias for filename mapping.
Alias /railsapp "/website/root/railsapp/public"
## We need the Rewrite Engine for this.
RewriteEngine on
<IfDefine debug>
## If debugging, turn on logging.
RewriteLogLevel 9
RewriteLog "/website/logs/http.rewrite.log"
</IfDefine>
## Check for a static root page.
RewriteRule ^/railsapp/?$ /railsapp/index.html [QSA]
## Check for Rails caching.
RewriteRule ^(/railsapp/[^.]+)$ $1.html [QSA]
## Redirect all non-static requests to Rails.
# Don't proxy on sub-requests (needed to make the LA-U work).
RewriteCond %{IS_SUBREQ} false
# Use look-ahead to see if the filename exists after all the rewrites.
RewriteCond %{LA-U:REQUEST_FILENAME} !-f
# Proxy it to Rails.
RewriteRule ^/railsapp(.*)$ http://127.0.0.1:9999%{REQUEST_URI} [P,QSA,L]
## Make sure Rails requests are reversed correctly.
ProxyPassReverse /railsapp http://127.0.0.1:9999/railsapp
## Disable keepalive; railsappd doesn't support them.
SetEnv proxy-nokeepalive 1
精彩评论