Search code examples
phpnginxstaticfpm

Nginx + PHP-FPM redirect to static PHP file


Some details about my setup first:

  • I am serving a static webapp (HTML + JS) from default Nginx webroot
  • I have a PHP-FPM server running on localhost:9000
  • The destination file should be /api/webroot/index.php for FPM (always, no need to try_files etc.)
  • I need to forward all /api and /api-debug calls to arrive at localhost:9000, and the /app/webroot/index.php should handle all these requests.

I have the following working Nginx configuration:

upstream fastcgi_backend {
    server localhost:9000;
    keepalive 30;
}

server {
    listen   80;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;

        location ~ ^/(api|api-debug)/ {
            root       /app/webroot;
            index      index.php;
            try_files  $uri /api/index.php$is_args$args;

            location ~ \.php$ {
                fastcgi_pass   fastcgi_backend;

                fastcgi_split_path_info ^(?:\/api\/)(.+\.php)(.*)$;
                fastcgi_param  SCRIPT_FILENAME /app/webroot/$fastcgi_script_name;

                include        fastcgi_params;
            }
        }
    }
}

I just want to make it more simple and efficient, because as I see it now it's a mess. I tried to adjust for example

try_files $uri /api/index.php$is_args$args;

to

try_files $uri /api/webroot/index.php$is_args$args;

and it failed... The only reason that it works is that /api/index.php includes /api/webroot/index.php, but I see it's inefficient.

I found debugging nginx config hard, because it's not easy to test.

Thank you very much for your help in advance!


Solution

  • The simplest solution would be to hardwire SCRIPT_FILENAME with a value of /app/webroot/index.php and remove one of your location blocks altogether.

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }
    
    location ~ ^/(api|api-debug)/ {
        include        fastcgi_params;
        fastcgi_param  SCRIPT_FILENAME /app/webroot/index.php;
        fastcgi_pass   fastcgi_backend;
    }
    

    Alternatively, to keep the flexibility of specifying a URI with a .php extension, you could simplify the configuration with:

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    
        rewrite ^/(api|api-debug)/ /index.php last;
    }
    
    location ~ \.php$ {
        include        fastcgi_params;
        fastcgi_param  SCRIPT_FILENAME /app/webroot$uri;
        fastcgi_pass   fastcgi_backend;
    }