Nginx – Is it possible to extend a 504 timeout in nginx on a per location basis

nginxphp-fpmubuntu-14.04

Is it possible to set timeout directives within a location block to prevent nginx returning a 504 from a long running PHP script (PHP-FPM)?

server
{
  listen 80;
  server_name ubuntu-vm.test-api;
  root /home/me/Sites/path/to/site/; 
  index index.php;

  location / {
    try_files $uri $uri/ /index.php?$query_string;
  }

  location ~ \.php$ {


    try_files $uri =404;

    # Fix for server variables that behave differently under nginx/php-fpm than typically expected
    fastcgi_split_path_info ^(.+\.php)(/.+)$;

    # Include the standard fastcgi_params file included with nginx
    include fastcgi_params;
    fastcgi_param  PATH_INFO        $fastcgi_path_info;
    fastcgi_index index.php;

    # Override the SCRIPT_FILENAME variable set by fastcgi_params
    fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;

    # Pass to upstream PHP-FPM; This must match whatever you name your upstream connection
    fastcgi_pass unix:/var/run/php5-fpm.sock;

    }

    location /someurlpath {

    try_files $uri $uri/ /index.php?$query_string;

    # Fix for server variables that behave differently under nginx/php-fpm than typically expected
    fastcgi_split_path_info ^(.+\.php)(/.+)$;

    # Include the standard fastcgi_params file included with nginx
    include fastcgi_params;
    fastcgi_param  PATH_INFO        $fastcgi_path_info;
    fastcgi_index index.php;

    # Override the SCRIPT_FILENAME variable set by fastcgi_params
    fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;

    # Pass to upstream PHP-FPM; This must match whatever you name your upstream connection
    fastcgi_pass unix:/var/run/php5-fpm.sock;

    fastcgi_read_timeout 100000s;
    }

    error_log /var/log/nginx/my_api_error.log;
    access_log /var/log/nginx/my_api_access.log;
}

This has no effect when making a request to example.com/someurlpath. The timeout occurs after approximately 60 seconds. PHP is configured to allow the script to run until completion (set_time_limit(0))

If I set the fastcgi_read_timeout in the main ~ /.php {} block this resolves the issue.

I don't want to set a global timeout for all scripts.

Best Answer

First, take a look at nested locations. The reason why your second location block isn't taken into account is because when nginx matches a location, it stops. So, http://ubuntu-vm.test-api/someurlpath, if theres an index.php in the corresponding folder, only matches the location ~ \.php$ !

I've stumbled upon this interesting blog post

To sum this up, you need to:

  1. Increase the max_execution_time configuration variable in your php.ini.
  2. Increase the request_terminate_timeout configuration variable of php-fpm.
  3. Set the fastcgi_read_timeout in the location you want, in the nginx configuration file.

The trouble is you can't tell php-fpm to use a different configuration file only for that one location.

However, you can set a php.ini configuration variable in your nginx configuration like so:

fastcgi_param PHP_VALUE "max_execution_time=1000";