Question

I'm hoping somebody might be able to shed some light on this. We have a Rails 2 app that generates PDF's using the wicked_pdf library. We're running the app under unicorn proxied by nginx.

The trouble is that whenever the app tries to serve a PDF it just times out and nginx reports a 404. I've checked the app via the unicorn port and it works fine so it's something happening between unicorn and nginx that's causing this to fail.

Log files are not reporting anything useful. The application log just reports everything normally but doesn't output the Sending data line. The nginx log reports *443 upstream prematurely closed connection while reading response header from upstream, client.

The unicorn error log reports that the connection is timing out and the worker is being killed, but the PDF generation does not take 30 seconds:

worker=2 PID:14099 timeout (31s > 30s), killing
reaped #<Process::Status: pid=14099,signaled(SIGKILL=9)> worker=2
worker=2 ready

I feel like we've missed something in the nginx configuration for the site, but I'm not sure where to start looking.

I've included the nginx config below:

server {
    listen *:80;
    server_name server_name.example.com;
    root /var/apps/application/current/public;
    try_files /system/maintenance.html $uri $uri/index.html @app;
    location @app {
        proxy_pass http://unix:/tmp/application.sock;
        proxy_set_header Host $http_host;
    }
    error_page 404 400 500 502 /error.html;
    location = /error.html {
        root /var/www;
    }
}
Was it helpful?

Solution 2

Ok, after a few hours of poking around I've finally solved this one.

When I set the timeouts to be big enough the PDF would eventually come through, which pointed to it being a timeout somewhere else. It eventually turned out that I was accessing request.env['HTTP_HOST'] in the layout file for the PDF to create an absolute path for an image. This was causing wkhtmltopdf to try and connect back to the server on the wrong hostname and it was failing.

The solution was to swap it out for an absolute file system path.

OTHER TIPS

Try setting this in you environment file:

ActionController::Streaming::X_SENDFILE_HEADER = 'X-Accel-Redirect' 

Note: this works for Nginx, not Apache.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top