Skip to content

Instantly share code, notes, and snippets.

@djo
Last active December 21, 2023 07:08
Show Gist options
  • Star 12 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save djo/11374407 to your computer and use it in GitHub Desktop.
Save djo/11374407 to your computer and use it in GitHub Desktop.
Rails, Nginx, XSendfile, and X-Accel-Mapping
# Symlink the shared protected folder
run "ln -nfs #{shared_path}/protected #{latest_release}/protected"
def download
send_file @document.file.path
# path: /app/releases/20140101010101/protected/file.pdf
end
# Defines the internal location to support the X-Sendfile feature
# for the delivery of static files from the folder: /app/shared/protected
# http://wiki.nginx.org/XSendfile
location /protected/ {
internal;
root /app/shared;
}
# Rack::Sendfile uses the X-Accel-Mapping header to map the file path (specified in the documents_controller.rb)
# to the internal location set in the nginx.conf.
# Rack::Sendfile takes a regular expression for the left hand side of the X-Accel-Mapping value:
# https://github.com/rack/rack-contrib/blob/master/lib/rack/contrib/sendfile.rb#L138
location @unicorn {
proxy_set_header X-Accel-Mapping /app/releases/[\d]+/protected/=/protected/;
}
# Specify the header only in the production.rb
# in order to allow Rails serving the files in the development:
config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect'
@etozzato
Copy link

Thanks, this finally helped me!

In my case, Ngnix was logging the error in relation to the rails assets. This is how I solved it, it might help someone else:

location /azz/ {
    internal;
    alias $RAILS_ROOT/public/assets;
  }

  location @rails {
    proxy_set_header  X-Real-IP  $remote_addr;
    proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_set_header X-Sendfile-Type X-Accel-Redirect;
    proxy_set_header X-Accel-Mapping $RAILS_ROOT/public/assets/=/azz/;
    proxy_redirect off;
    proxy_pass http://rails_app;
  }

Accessing the app on http://localhost (Ngnix) doesn't generate any warning. Accessing http://localhost:3000 (puma) still generates the warning, but I believe this is the expected outcome.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment