I am running a Rails 3 site on Ubuntu 8.04 with Nginx 1.0.0 and Passenger 3.0.7.
In my Nginx error.log I started seeing the message X-Accel-Mapping header missing
quite a lot. Googling lead me to the docs of Rack::Sendfile
and to the Nginx docs.
Now, my app can be accessed through several domains and I am using send_file
in my app to deliver some files specific to the domain they are requested from, e.g., if you come to domain1.com/favicon.ico
I look up the favicon in at public/websites/domain1/favicon.ico
.
This works fine and I don't think I need/want to get Nginx involved and create some private area where I store those files, as the samples in the Rack::Sendfile
docs suggest.
How can I get rid of the error message?
this message means that Rack::Sendfile
disabled X-Accel-Redirect
for you, because you have missing configuration for it in nginx.conf...
I'm using Nginx + Passenger 3 + Rails 3.1.
Gathered information from this pages I've figured it out:
http://greenlegos.wordpress.com/2011/09/12/sending-files-with-nginx-x-accel-redirect
http://code.google.com/p/substruct/source/browse/trunk/gems/rack-1.1.0/lib/rack/sendfile.rb?r=355
Serving Large Files Through Nginx via Rails 2.3 Using x-sendfile
I have controller which maps /download/1
requests to storage files which have their own directory structure, like this: storage/00/00/1
, storage/01/0f/15
etc. So I need to pass this through Rails, but then I need to use send_file
method which will use X-Accel-Redirect
to send the final file to the browser through nginx directly.
Within the code I have this:
send_file(
'/var/www/shared/storage/00/00/01',
:disposition => :inline,
:filename => @file.name # an absolute path to the file which you want to send
)
I replaced the filename for this example purposes
Now I had to add these lines to my nginx.conf
:
server {
# ...
passenger_set_cgi_param HTTP_X_ACCEL_MAPPING /var/www/shared/storage/=/storage/;
passenger_pass_header X-Accel-Redirect;
location /storage {
root /var/www/shared;
internal;
}
# ...
}
The path /storage
is not visible from outside world, it is internal only.
Rack::Sendfile
gets the header X-Accel-Mapping
, extracts the path from it and replaces /var/www/shared/storage
with /storage...
. Then it spits out the modified header:
X-Accel-Redirect: /storage/00/00/01
which is then processed by nginx.
I can see this works correctly as the file is downloaded 100x faster than before and no error is shown in the logs.
Hope this helps.