Nginx – How to debug nginx + php-fpm download failures

cloudflarecompressionnginxphp-fpmUbuntu

Downloads fail after all data downloaded on nginx + php-fpm.

I'm controlling downloads of zip files (roughly 100mb each) with a PHP script that streams the file directly to the client. I'm using php-fpm under Ubuntu 14.04 with nginx. Occasionally the download succeeds, but generally it fails after streaming all the data.

The download proceeds all the way to the end on both Chrome and Firefox client browsers, but then it hangs and fails. Sometimes the zip file just has the wrong name "foo.zip.crdownload" and sometimes it is corrupted. What can I do to debug this?

(Edit: nothing was showing in the logs, but finally a failed download showed up with "upstream timed out (110: Connection timed out) while reading response header from upstream, client")

I'm going through the CloudFlare CDN/Proxy, but the site was working through Apache 2 before today. I've disabled caching for the URL I'm downloading from. I also tried changing the mime type from 'application/octet-stream' to 'application/zip' and it still intermittently fails.

Best Answer

It seems to be partly a timeout. This tekovic link helped: Basically you need to set the fastcgi_read_timeout value in the content section to a reasonably number of seconds allowed before download starts (defaults to 60s).

location ~* \.php$ {
    include         fastcgi_params;
    fastcgi_index   index.php;
    fastcgi_read_timeout 120;
    fastcgi_pass    127.0.0.1:9000;
    fastcgi_param   SCRIPT_FILENAME    $document_root$fastcgi_script_name;
}

According to the nginx wiki

"Directive sets the amount of time for upstream to wait for a fastcgi process to send data. Change this directive if you have long running fastcgi processes that do not produce output until they have finished processing. If you are seeing an upstream timed out error in the error log, then increase this parameter to something more appropriate."

Next, I configured CloudFlare to not cache the particular directory the download happens from and to not keep it "Always On" -- the page rule pattern should be like this

*mywebsite.com/downloads/*