Home > Back-end >  Laravel - Nginx, Root Directory Based on path
Laravel - Nginx, Root Directory Based on path

Time:05-17

I have a situation where I need to serve all the requests from https://example.com/api/v1 from a different folder let's say /var/www/firstversion/public and https://example.com/api/v2 from other folder /var/www/secondversion/public

Below is how my current configuration looks like

server {
        root /var/www/firstversion/public/;
        index index.html index.php index.htm index.nginx-debian.html;
        server_name example.com;

        location / {
              try_files $uri $uri/ /index.php$is_args$args;
        }
        location /api/v2/ {
                alias /var/www/secondversion/public/;
                try_files $uri $uri/ /index.php$is_args$args;
        }
        location ~ \.php$ {
                include snippets/fastcgi-php.conf;
                fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
              
        }
        location ~ /\.ht {
                deny all;
        }

}

The problem here is that I am getting response always from the /var/www/firstversion/public/. However, to verify whether the location block is being selected I tried adding return 302 https://google.com and it worked. So the location pattern is matching but somehow the alias/root isn't working. Can someone point in the right direction or what am i missing?

CodePudding user response:

The very first thing that you are missing is that the last try_files directive parameter treated as a new URI to reevaluate from the beginning. That is, after the request like /api/v2/some/route gets handled with your location /api/v2/ { ... } and there are oblivious no such a /var/www/secondversion/public/some/route physical file or directory on your local filesystem, an internal rewrite to /index.php$is_args$args takes place. After that the rewritten URI gets handled with your location ~ \.php$ { ... } PHP-FPM handler which inherits its root as /var/www/firstversion/public/ from the upper configuration level.

The try_files directive when being used with the alias one has long standing side effects which I don't think to be fixed at least until the major nginx version gets changed since there are too many configurations exists adopted to those effects in some way. When you need to host some complex PHP-based system (e.g. WordPress) under some URI prefix, a workaround like shown here can be used, with the nested PHP handler being declared. However you case is completely different, and actually to just serve some API you don't need such a complex approach.

You should understand that you don't need to stuck with that location ~ \.php$ { ... } to process the PHP file via PHP-FPM daemon at all, as well as you don't need to stuck with that some kind of predefined PHP handler snippets/fastcgi-php.conf (which I suppose is something like shown here). Instead, if all the requests should be handled exclusively with the index.php from the first or the second backend app, you are free to define your custom PHP handler in a way like the following one:

map $uri $api_root {
    ~^/api/v2    /var/www/secondversion/public;
    default      /var/www/firstversion/public;
}
server {
    ...
    location ^~ /api/ {
        include fastcgi_params;
        # redefine some FastCGI parameters
        fastcgi_param DOCUMENT_ROOT $api_root;
        fastcgi_param SCRIPT_NAME /index.php;
        fastcgi_param SCRIPT_FILENAME $api_root/index.php;
        fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
    }
}
  • Related