How To: Set up X-Accel-redirect for send_file with nginx, rails and passenger 5

Published 02 August 2017 under software

If you need provide the ability for users to download protected files when using rails you can store the files in a non-public directory and serve them within a rails action using send_file. In order keep the downloads efficient it's worth getting nginx to serve the files rather than serving them directly in rails. The snippets below assume Phusion passenger 5 and nginx. In your nginx config (in /etc/nginx/sites-available/mysite for example):

server {
        server_name example.com;

        root /var/www/example/public;
        rails_env production;

        passenger_enabled on;
        passenger_set_header X-Sendfile-Type "X-Accel-Redirect";
        passenger_env_var HTTP_X_ACCEL_MAPPING /mnt/data/=/uploads/;
        passenger_pass_header X-Accel-Redirect;

        location ~ /uploads/(.*) {
                alias /mnt/data/$1;
                internal;
        }
}

We assume above that you're storing the files in /mnt/data.

The files can then be served from the rails app using something like the following:

  def show
    @document = Document.find(params[:id])
    authorize @document, :show?

    send_file "/mnt/data/#{@document.upload_path}", filename: @document.original_filename
  end

Comments

blog comments powered by Disqus