NGINX config for php backend and JS frontend

490

I'm trying to serve my frontend app under /, but have requests for /oauth2 pass off to a php backend. Here is my latest nginx config attempt:

upstream dockerphp {
    server backendphp:9000;
}

server {
    listen       80;
    server_name  localhost;
    index index.html;
    root   /application/frontend/build;

    location /oauth2 {
        root   /application/public;
        index index.php;
        try_files $uri $uri/ /index.php$is_args$args;
        #try_files /index.php$is_args$args =404;

        location ~ \.php$ {
            include /etc/nginx/fastcgi_params;

            fastcgi_split_path_info ^(.+\.php)(/.+)$;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            fastcgi_param PATH_INFO $fastcgi_path_info;
            fastcgi_pass  dockerphp;
            fastcgi_index index.php;
        }
    }

    location / {
        try_files $uri $uri/ /index.html;
    }
}

I've tried just about every combination of config I can think of and just can't get it to work. Most of the time I end up with 404s.

Both my nginx and php docker containers have the same /application directory mounted.

With the above config, any requests to /oauth2/blah are being picked up by the location block at the bottom and therefore back to my frontend. This is probably my biggest problem - the /oauth2 location block to my mind is more "specific" so why isn't it "winning"?

I tried the commented out try_files line instead (to see whether index.php being the "fallback" value had an effect on specificity), and nginx just started downloading the index.php file rather than passing on the request. Help?

609

Answer

Solution:

This is the approach that I use:

  1. attempt to serve js / static pages first
  2. if 1.) fails, pass to PHP backend
  3. define a location for handling .php
    upstream dockerphp {
        server backendphp:9000;
    }


    server {
        listen           80;
        server_name      localhost;
        index            index.html;
        root             /application/frontend/build;

        location / {
            try_files    $uri $uri/ @php;
        }

        location @php {
            root         /application/public;
            index        index.php;
            try_files    $uri $document_root/index.php?$query_string; 
            # $document_root/index.php is the important part due to how root and alias directives work
        }

        location ~ \.php$ {
            include      /etc/nginx/fastcgi_params;

            fastcgi_split_path_info ^(.+\.php)(/.+)$;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            fastcgi_param PATH_INFO $fastcgi_path_info;
            fastcgi_pass  dockerphp;
            fastcgi_index index.php;
        }
    }
414

Answer

Solution:

Thelocation /oauth2 only wins when the URL you try is exactlywebsite.com/oauth2. Add^~ and the route will win all of the URLs starting with/oauth2, like this:

location ^~ /oauth2 {
215

Answer

Solution:

For reference I eventually found a simple working solution (below).

upstream dockerphp {
    server backendphp:9000;
}

server {
    listen       80;
    server_name  localhost;
    index        index.html;
    root         /application/frontend/build;

    location / {
        try_files $uri $uri/ /index.html;
    }

    location /oauth2 {
        try_files $uri $uri/ @php;
    }

    location @php {
        include                  /etc/nginx/fastcgi_params;
        fastcgi_pass             dockerphp;
        fastcgi_param            SCRIPT_FILENAME /application/public/index.php;
    }
}

People are also looking for solutions to the problem: php - Nginx "No such file or directory error" for existing file path with appropriate permissions

Source

Didn't find the answer?

Our community is visited by hundreds of web development professionals every day. Ask your question and get a quick answer for free.

Ask a Question

Write quick answer

Do you know the answer to this question? Write a quick response to it. With your help, we will make our community stronger.

Similar questions

Find the answer in similar questions on our website.