Score:1

How do I configure nginx to remove a part of the URI given to index.php

mc flag

The routing script of my application expects the URI to be

/api/v0/create

My request goes to

http://my-server.test/subdir/api/v0/create

How can I configure nginx to remove the "/subdir" from the URI, providing the expected path to the application's router?

I tried this one, but got only "404 File not found" from the server (not the app):

location /subdir/api/ {
    rewrite ^/subdir(.*)$ $1 last;
    try_files $uri $uri/ /subdir/api/public/index.php$is_args$args;
}

With the rewrite flag break and without the rewrite part altogether I get a 404 from my application for the subdir still in URI.

Edit:

I need a way without redirect to /api for there is another analogue URI http://my-server.test/anothersubdir/api/v0 which would have the same /api part.

All this comes down to the question: Is there a way to configure nginx to give the target application a rewritten URI in a way that for example $_SERVER['REQUEST_URI'] in php reflects it?

Edit: Here is the complete nginx configuration:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
# configuration file /etc/nginx/nginx.conf:

user  nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    access_log  /var/log/nginx/access.log  main;
    sendfile        on;
    #tcp_nopush     on;
    keepalive_timeout  65;
    #gzip  on;
    include /etc/nginx/conf.d/*.conf;
}

# configuration file /etc/nginx/mime.types:
types {
    text/html                                        html htm shtml;
    ... omitted
}

# configuration file /etc/nginx/conf.d/php.conf:
server {
    listen 80;
    server_name my-server.test;
    root /var/www;

    location /subdir/api/ {
        rewrite ^/subdir(.*)$ $1 last;
        try_files $uri $uri/ /subdir/api/public/index.php$is_args$args;
        location ~* \.php$ {
            fastcgi_split_path_info ^(.+\.php)(/.+)$;
            fastcgi_pass   php:9000;
            include fastcgi_params;
            fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
            fastcgi_param  SCRIPT_NAME     $fastcgi_script_name;
        }
    }
}

Thank you for helping!

us flag
Please add output of `nginx -T` to the question so that we can see the full nginx configuration.
hangerer avatar
mc flag
@TeroKilkanen: Thanks for your comment - I put the nginx -T output.
djdomi avatar
za flag
Does this answer your question? [Nginx reverse proxy + URL rewrite](https://serverfault.com/questions/379675/nginx-reverse-proxy-url-rewrite)
hangerer avatar
mc flag
@djdomi: Thanks for the link, but I have no proxy to redirect to - the application should be served from the same server. I tried ```rewrite ^/subdir(.*)$ $1 break;``` also, but there is no other outcome, subdir is still in the path received by the app.
us flag
It is actually better to build support for prefixes like this in the application itself. Especially if the application will create URLs that refer to itself, it needs the knowledge of the URL that is usable from outside.
hangerer avatar
mc flag
@TeroKilkanen: Yes, you're right, that seems the only way to handle this. Thank you!
Score:1
in flag

You don't have any location block that will handle the request after the redirect (lets say after the rewrite, your request changes from /subdir/api/v0/create to this /api/v0/create, there's no matching block that will process such requests. I would suggest to take out the nested location block outside, also add the root location block (if needed)

server {
    listen 80;
    server_name my-server.test;
    root /var/www;

    location /subdir/api/ {
        rewrite ^/subdir(.*)$ $1 permanent;
        try_files $uri $uri/ /subdir/api/public/index.php$is_args$args;
    }

    location ~* \.php$ {
            fastcgi_split_path_info ^(.+\.php)(/.+)$;
            fastcgi_pass   php:9000;
            include fastcgi_params;
            fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
            fastcgi_param  SCRIPT_NAME     $fastcgi_script_name;
    }

    location / {
        <REST OF YOUR CONFIGURATION>
    }
}
hangerer avatar
mc flag
Thank you, this surely works, if I put the ```try_files``` block in a location which matches ```/api```. Unfortunately I made not clear in my question that I need a solution without redirect to /api/... for I have another similar looking applications: ```http://my-server.test/anothersubdir/api/v0``` which would conflict in this way.
I sit in a Tesla and translated this thread with Ai:

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.