NGINX: Set up a project from a path (/api) and define routes in the code from the root (/)

95 Views Asked by At

I am trying to set up a Laravel application on NGINX with the following config:

server {
    listen 443 ssl;
    server_name {MY-IP}; # The project is mounted on an IP
    # ssl_certificate ...
    # ssl_certificate_key ...;

    root /var/www/myproject-ui;
    index index.html index.htm index.php;
    charset utf-8;

    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Content-Type-Options "nosniff";

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

    location /api {
        alias /var/www/myproject/public;
        try_files $uri $uri/ @laravelapi;

        location ~ \.php$ {
            include snippets/fastcgi-php.conf;
            fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
            fastcgi_param SCRIPT_FILENAME $request_filename;
            fastcgi_read_timeout 120s;  # Set the maximum timeout to 2 minutes
        }
    }

    location /auth {
        alias /var/www/myproject/public;
        try_files $uri $uri/ @laravelapi;

        location ~ \.php$ {
            include snippets/fastcgi-php.conf;
            fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
            fastcgi_param SCRIPT_FILENAME $request_filename;
            fastcgi_read_timeout 120s;  # Set the maximum timeout to 2 minutes
        }

    }

    location /logs {
        alias /var/www/myproject/public;
        try_files $uri $uri/ @laravelapi;

        location ~ \.php$ {
            include snippets/fastcgi-php.conf;
            fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
            fastcgi_param SCRIPT_FILENAME $request_filename;
            fastcgi_read_timeout 120s;  # Set the maximum timeout to 2 minutes
        }
    }

    location /storage {
        alias /var/www/myproject/public/storage;
    }

    location /tinker {
        alias /var/www/myproject/public;
        try_files $uri $uri/ @laravelapi;

        location ~ \.php$ {
            include snippets/fastcgi-php.conf;
            fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
            fastcgi_param SCRIPT_FILENAME $request_filename;
            fastcgi_read_timeout 120s;  # Set the maximum timeout to 2 minutes
        }
    }

    location @laravelapi {
        rewrite /api/(.*)?$ /api/index.php?$is_args$args last;
        rewrite /auth/(.*)?$ /auth/index.php?$is_args$args last;
        rewrite /logs/(.*)?$ /logs/index.php?$is_args$args last;
        rewrite /storage/(.*)?$ /storage/index.php?$is_args$args last;
        rewrite /tinker/(.*)?$ /tinker/index.php?$is_args$args last;
    }

    location = /favicon.ico {
        access_log off;
        log_not_found off;
    }

    location = /robots.txt {
        access_log off;
        log_not_found off;
    }

    error_page 404 /index.php;

    location ~ /\.(?!well-known).* {
        deny all;
    }
}

I need the routes /api, /auth, and /logs to be part of the Laravel project, while all other routes belong to the front-end (static HTML).

My problem is:

How can I make NGINX/Laravel interpret routes from the root (/) instead of from the defined paths /api or /auth?

For example:

If I try to access the route /api/v1/myroute, in Laravel, I would have to define it only as /v1/myroute, and that is not what I want. I want to define it as /api/v1/myroute. The issue is that I have packages like log-viewer and web-tinker with routes defined from the root (/tinker, /logs), and they don't work as it should because I have to access them like this:

/tinker/tinker

/logs/logs

I would also like to know if it is possible to use a regex to define all the routes in a single block, like:

^(api|auth|logs)

Because I already tried with:

^/(api|auth)

and it didn't worked for me.

1

There are 1 best solutions below

2
On

if you don't need the api specific security features like CORS, Scantum and bypassing the CSRF token provided by laravel framework

you can change prefix in file App\Providers\RouteServiceProvider.php

Route::prefix('api/v1')
    ->namespace($this->namespace)
    ->group(base_path('routes/api.php'));

remove the prefix of v1 and run cache clear artisan command this will allow the route to run the url with api prefix form Laravel

so, the above code as per your Nginx config will output as

old
domain.com/api/api/v1/myroute
new
domain.com/api/v1/myroute

in Nginx you define the /api end point to laravel host folder so it get append in new url